ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Android自助餐之Jni(四)在线导入so文件 - [Android自助餐之Jni四在线导入so文件](#) - [上传so文件到服务器](#) - [创建jni对应类](#) - [在应用创建时加载so文件](#) - [需要时进行调用](#) 下载[完整源代码](http://download.csdn.net/detail/xmh19936688/9395117) ### 上传so文件到服务器 此处已上传so文件到github。假设URL为:`https://raw.githubusercontent.com/***/libJniLibDemo.so` ### 创建jni对应类 本实例已知c文件内容如下 本实例已知c文件内容如下 ~~~ JNIEXPORT jstring JNICALL Java_com_xmh_jni_JniUtil_getResult(JNIEnv *env,jobject obj,jstring value){ char * str; str=(*env)->GetStringUTFChars(env,value,NULL); sprintf(str,"%s-_-%s",str,str); return (*env)->NewStringUTF(env, str); } ~~~ 因此所创建的类完整类名为:com.xmh.jni.JniUtil。文件内容如下 ~~~ public class JniUtil { /**so文件的URL*/ private static String LIB_FILE_NET_PATH="https://raw.githubusercontent.com/***/libJniLibDemo.so"; //region so文件加载状态 /**未加载*/ public static int LIBRARY_LOAD_STATUS_NONE=0; /**正在加载*/ public static int LIBRARY_LOAD_STATUS_LOADING=1; /**已加载*/ public static int LIBRARY_LOAD_STATUS_LOADED=2; /**so文件加载状态*/ private int libraryLoadStatus=LIBRARY_LOAD_STATUS_NONE; //endregion /**so文件加载回调*/ private DownloadStatusListener downloadStatusListener=null; //region 单例模式 private static JniUtil jniUtil=null; private JniUtil(){} public static JniUtil getInstance(){ if(jniUtil!=null)return jniUtil; return jniUtil=new JniUtil(); } //endregion /**获取so文件加载状态*/ public int getLibraryStatus(){ return libraryLoadStatus; } /**本地方法私有化,防止未加载就调用*/ public native String getResult(String value); /**封装后的本地方法*/ public String getResult(Context context,String value){ //先判断是否加载了so文件 if(libraryLoadStatus==LIBRARY_LOAD_STATUS_NONE) { loadLibrary(context); return null; } return getResult(value); } /**加载so文件*/ public void loadLibrary(Context context) { //设置加载状态 libraryLoadStatus=LIBRARY_LOAD_STATUS_LOADING; try { File libsDir = context.getDir("libs", Context.MODE_PRIVATE); final String soFilePath=libsDir.getAbsolutePath() + "/libJniLibDemo.so"; Uri uri=Uri.parse(LIB_FILE_NET_PATH); final DownloadRequest downloadRequest = new DownloadRequest(uri); downloadRequest.setRetryPolicy(new DefaultRetryPolicy());//默认重试逻辑 downloadRequest.setDestinationURI(Uri.parse(soFilePath)); downloadRequest.setDownloadListener(new DownloadStatusListener() { @Override public void onDownloadComplete(int id) { System.load(soFilePath); libraryLoadStatus=LIBRARY_LOAD_STATUS_LOADED;//设置加载状态 if(downloadStatusListener!=null) downloadStatusListener.onDownloadComplete(id); } @Override public void onDownloadFailed(int id, int errorCode, String errorMessage) { libraryLoadStatus=LIBRARY_LOAD_STATUS_NONE;//设置加载状态 if(downloadStatusListener!=null) downloadStatusListener.onDownloadFailed(id, errorCode, errorMessage); } @Override public void onProgress(int id, long totalBytes, long downloadedBytes, int progress) { if(downloadStatusListener!=null) downloadStatusListener.onProgress(id,totalBytes,downloadedBytes,progress); } }); new ThinDownloadManager().add(downloadRequest); } catch (Exception e) { //设置加载状态 libraryLoadStatus=LIBRARY_LOAD_STATUS_NONE; e.printStackTrace(); } } /**设置so文件加载回调*/ public void setOnDownloadListener(DownloadStatusListener listener){ this.downloadStatusListener =listener; } } ~~~ ### 在应用创建时加载so文件 重写Application类如下 ~~~ public class JniApplication extends Application{ /**在应用创建时开始加载so文件*/ @Override public void onCreate() { super.onCreate(); Log.e("xmh-jni", "app-create"); JniUtil.getInstance().loadLibrary(this); } } ~~~ ### 需要时进行调用 ~~~ final JniUtil jniUtil = JniUtil.getInstance(); //判断是否已加载so文件,如已加载则调用封装后的本地方法,否则设置加载回调后开始加载so文件 if(jniUtil.getLibraryStatus()==JniUtil.LIBRARY_LOAD_STATUS_LOADED) { tvResult.setText(jniUtil.getResult(this, "xmh")); }else { jniUtil.setOnDownloadListener(new DownloadStatusListener() { @Override public void onDownloadComplete(int id) { //加载完成后执行操作 tvResult.setText(jniUtil.getResult(MainActivity.this, "xmh")); } @Override public void onDownloadFailed(int id, int errorCode, String errorMessage) { } @Override public void onProgress(int id, long totalBytes, long downloadedBytes, int progress) { } }); jniUtil.loadLibrary(this); } ~~~