Android自助餐之Jni(四)在线导入so文件

Android自助餐之Jni(四)在线导入so文件

Android自助餐专栏

Android自助餐之Jni(一)最简单的运行

Android自助餐之Jni(二)静态导入so文件

Android自助餐之Jni(三)动态导入so文件

Android自助餐之Jni(四)在线导入so文件

Android自助餐之Jni(五)进阶

Android自助餐之Jni(六)NDK入门

下载完整源代码

上传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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值