Android so lib库远程http下载和动态注册

1、背景java

 

   在开发Android应用程序的实现,有时候须要引入第三方so lib库,但第三方so库比较大,例如开源第三方播放组件ffmpeg库, 若是直接打包的apk包里面, 整个应用程序会大不少.通过查阅资料和实验,发现经过远程下载so文件,而后再动态注册so文件时可行的。主要须要解决下载so文件存放位置以及文件读写权限问题。android

 

2、主要思路网络

 

一、首先把so放到网络上面,好比测试放到:http://codestudy.sinaapp.com/lib/test.soapp

二、应用启动时,启动异步线程下载so文件,并写入到/data/data/packageName/app_libs目录下面异步

三、调用System.load 注册so文件。因路径必须有执行权限,咱们不能加载SD卡上的so,但能够经过调用context.getDir("libs", Context.MODE_PRIVATE)把so文件写入到应用程序的私有目录/data/data/packageName/app_libs。ide

 

3、代码实现测试

 

 一、网络下载so文件,并写入到应用程序的私有目录/data/data/PackageName/app_libsurl

/**
     * 下载文件到/data/data/PackageName/app_libs下面
     * @param context
     * @param url
     * @param fileName
     * @return
     */
    public static File downloadHttpFileToLib(Context context, String url, String fileName) {
        long start = System.currentTimeMillis();
        FileOutputStream outStream = null;
        InputStream is = null;
        File soFile = null;
        try {
            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(url);
            HttpResponse response = client.execute(get);
            HttpEntity entity = response.getEntity();
            File dir = context.getDir("libs", Context.MODE_PRIVATE);
            soFile = new File(dir, fileName);
            outStream = new FileOutputStream(soFile);
            is = entity.getContent();
            if (is != null) {
                byte[] buf = new byte[1024];
                int ch = -1;
                while ((ch = is.read(buf)) > 0) {
                    outStream.write(buf, 0, ch);
                    //Log.d(">>>httpDownloadFile:", "download 进行中....");
                }
            }
            outStream.flush();
            long end = System.currentTimeMillis();
            Log.d(">>>httpDownloadFile cost time:",  (end-start)/1000 + "s");
            Log.d(">>>httpDownloadFile:", "download success");
            return soFile;
        } catch (IOException e) {
            Log.d(">>>httpDownloadFile:", "download failed" + e.toString());
            return null;
        } finally {
            if (outStream != null) {
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 

 二、调用System.load 注册so文件线程

new Thread(new Runnable() {
      @Override
      public void run() {
          File soFile = FileUtils.downloadHttpFileToLib(getApplicationContext(), "http://codestudy.sinaapp.com//lib/test.so", "test.so");
          if (soFile != null) {
            try {
                   Log.d(">>>loadAppFile load path:", soFile.getAbsolutePath());
                   System.load(soFile.getAbsolutePath());
             } catch (Exception e) {
                 Log.e(">>>loadAppFile load error:", "so load failed:" + e.toString());
             }
           }
      }
}).start();

  

4、须要解决的问题code

 

一、so文件下载以及注册时机。测试发现libffmpeg.so  8M的文件单线程下载须要10-13s左右

二、so下载失败或者注册失败该怎么处理。例如so播放组件是否尝试采用android系统原生MediaPlayer进行播放

三、当初次so尚未下载完注册成功时,进入播放页面时,须要友好提示用户,好比loading 视频正在加载等等

四、无网络状况等等状况

 

5、说明

 

上面的demo通过3(2.3/4.2/4.4)实际机型测试能够正常使用,而后根据第四点列举问题完善如下,便可使用。

相关文章
相关标签/搜索