zoukankan      html  css  js  c++  java
  • Android so lib库远程http下载和动态注册

    一、背景

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

    二、主要思路

     

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

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

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

    三、代码实现

     

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

    /**
         * 下载文件到/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();
                    }
                }
            }
        }
    

     2、调用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();
    

      

    四、需要解决的问题

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

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

    3、当初次so还没有下载完注册成功时,进入播放页面时,需要友好提示用户,比如loading 视频正在加载等等

    4、无网络情况等等情况

     

    五、说明

     

     上面的demo经过3(2.3/4.2/4.4)实际机型测试可以正常使用,然后根据第四点列举问题完善以下,即可使用。

  • 相关阅读:
    bzoj2400 Spoj 839 Optimal Marks
    01分数规划
    bzoj1565 植物大战僵尸
    bzoj1497 最大获利(最大权闭合子图)
    bzoj3144 切糕
    loj6045 价
    bzoj3894 文理分科
    luogu3731 新型城市化
    快速傅里叶变换(FFT)
    bzoj1030 文本生成器
  • 原文地址:https://www.cnblogs.com/hubcarl/p/4203254.html
Copyright © 2011-2022 走看看