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)实际机型测试可以正常使用,然后根据第四点列举问题完善以下,即可使用。

时间: 2024-08-09 01:18:33

Android so lib库远程http下载和动态注册的相关文章

android adt升级到版本22后,就无法再向lib库里面添加jar了

目前有一个android app 大项目,引用了很多的类库,一直运行的好好的,今天我把Eclipse ADT插件升级到了最新版本(v22),同时把sdl也升级了.在整个 升级过程中很好,没有任何问题,当我达成apk在手机上运行时,报错了NoClassDefFoundError java.lang.NoClassDefFoundError:org.acra.ACRA .... 该ARCA库一斤包含到了lib库里面了,我能在Android Private Libraries 中看到,并且编译错误.在

android 如何添加第3方lib库到kernel中

注意:只能将lib库放在kernel编译到的地方,如下: alps/kernel/ alps/mediatek/custom/common/kernel/ alps/mediatek/custom/$platform/kernel/ alps/mediatek/custom/$proj/kernel/ alps/mediatek/kernel/ alps/mediatek/platform/$platform/kernel/core/ alps/mediatek/platform/$platfo

Android 获取并显示远程图片 Picasso框架的使用(一)

转载请注明出处:明桑Android 在Android开发中,常需要从远程获取图片并显示在客户端,当然我们可以使用原生HttpUrlConnection和AsyncTask等操作来完成,但并不推荐,因为这样不仅需要我们编写大量的代码,还需要处理缓存和下载管理等,最好自己封装成库或者采用第三方库: Picasso:A Powerful Image Downloading and Caching Library for Android 根据名字就知道它是跟什么相关了(Picasso:毕加索)它的基本操

基于Google Volley的Android Http连接库

android http lib based on volley-基于Google Volley的Http库 项目Github地址:https://github.com/sddyljsx/android-http-lib-based-on-volley 使用说明: 一.优化了volley的组织结构,重新定义的包架构更加清晰明了,方便阅读,扩展 包组织结构图如下所示: base包中包括了volley架构的基础类,抽象类. impl包中包括了base包中类的具体实现. process包中包括了网络请

Android开源工具库

 一.依赖注入DI 通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 1. AndroidAnnotations(Code Diet) android快速开发框架 项目地址:https://github.com/excilys/androidannotations 文档介绍:https://github.com/excilys/androidannotations/wiki 官方网站:http://androidannotations.org/ 特点:(1)依赖注入:包

Android底层笔记:APP通过JNI调用动态库.so

开发环境: 平板电脑:FSPAD-733,原理上来说任何支持安卓的开发板都可以: eclipse:使用的是iTOP-4412开发板提供的eclipse安卓开发包: Ubuntu:使用的是FSPAD-733虚拟机开发环境,原理上来说任何开发包提供的虚拟机环境都是可以的. 加载库名,然后系统自动到库目录下找.so动态库 目录/库文件名 loadLibrary ? ? ? du -mh tags androidL/art/ vi -t Runtim_nativeLoad ? ? ? javah -jn

第一行代码——Android高清版pdf免费下载

下载地址:网盘下载 备用地址:网盘下载 目录:编辑第1章----------- 开始启程,你的第一行Android代码 1.1 了解全貌,Android王国简介2 1.1.1 Android系统架构2 1.1.2 Android已发布的版本 3 1.1.3 Android应用开发特色 4 1.2 手把手带你搭建开发环境 5 1.2.1 准备所需要的软件 5 1.2.2 搭建开发环境 6 1.3 创建你的第一个Android项目 11 1.3.1 创建HelloWorld项目 11 1.3.2 运

Android程序 依赖库引用Gson 报java.lang.NoClassDefFoundError: com/google/gson/Gson 解决方法

Android 程序所依赖一个Library程序B , B 程序中用到格式化json串,转换成标准json串的要求 public static String jsonFormatter(String uglyJSONString) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); JsonParser jp = new JsonParser(); JsonElement je = jp.parse(uglyJSONStri

android调用第三方库——第一篇 (转载)

转自:http://blog.csdn.net/jiuyueguang/article/details/9447245 版权声明:本文为博主原创文章,未经博主允许不得转载. 0:前言: 这两天一直在研究用android的jni调用第三方库,上网搜方法,但是都是泛泛而谈,没有demo,经过我几番折磨,写了n多的 helloword工程,总是不成功,工程名字也就由helloowrd转到shithelloword再转到fuckhelloword再转到 bitchhelloword再转到ganhello