相关阅读
插件化知识梳理(1) - Small 框架之如何引入应用插件
插件化知识梳理(2) - Small 框架之如何引入公共库插件
插件化知识梳理(3) - Small 框架之宿主分身
插件化知识梳理(4) - Small 框架之如何实现插件更新
插件化知识梳理(5) - Small 框架之如何不将插件打包到宿主中
插件化知识梳理(6) - Small 源码分析之 Hook 原理
插件化知识梳理(7) - 类的动态加载入门
插件化知识梳理(8) - 类的动态加载源码分析
插件化知识梳理(9) - 资源的动态加载示例及源码分析
插件化知识梳理(10) - Service 插件化实现及原理
一、前言
在前面的例子当中,我们都是把插件预置在Apk
当中一起安装的,如 插件化知识梳理(4) - Small 框架之如何实现插件更新 所示,我们初始时候会将代表插件的so
文件放置在jniLibs/armeabi
目录下。
那么如果我们将不是很重要的插件放在服务器上,当应用启动之后判断需要该插件,然后再从服务器上下载,将能够有效减小初始时候安装包的体积。
下面,我们就来演示一下如何从外部加载插件。
二、示例
加载插件部分的源码位于Bundle.java
中:
可以看到,加载插件有两种方式,它们是根据
Small.isLoadFromAssets
来区分:
- 如果该标志位为真,那么读取
/data/data/{host_pkg_name}/small_base/
下的插件,并且包名和插件的对应关系为:pkg_name -> {pkg_name}.apk
- 如果该标志位为假,那么读取
nativeLibraryDir
目录下的so
,并且包名和插件的对应关系为:pkg_name -> lib{pkg_name}.so
,也就是我们之前一直演示的方式。
通过这段源码,那么如何实现加载外部插件就有思路了:
- 删除调
jniLIbs/armeabi
下的so
文件 - 通过
Small.setLoadFromAssets
方法将标志位设为true
- 从网络上获取插件,创建
/data/data/{host_pkg_name}/small_base/{pkg_name}.apk
,通过文件流的形式将下载下来的插件写入到.apk
当中。
这里因为没有服务器,所以我们把预先编译好的插件.so
文件拷贝到外部存储中,从外部存储读取的过程就相当于是网络下载的过程:
private void initPlug() {
//表明需要从外部加载插件。
Small.setLoadFromAssets(true);
try {
File dstFile = new File(FileUtils.getInternalBundlePath(), "com.demo.small.update.app.upgrade.apk");
if (!dstFile.exists()) {
dstFile.createNewFile();
}
File srcFile = new File(Environment.getExternalStorageDirectory().toString() + "/Small/" + "libcom_demo_small_update_app_upgrade.so");
FileInputStream inputStream = new FileInputStream(srcFile);
OutputStream outputStream = new FileOutputStream(dstFile);
byte[] buffer = new byte[1024];
int length;
//将.so的内容写入到.apk当中。
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
更多文章,欢迎访问我的 Android 知识梳理系列:
- Android 知识梳理目录:http://www.jianshu.com/p/fd82d18994ce
- 个人主页:http://lizejun.cn
- 个人知识总结目录:http://lizejun.cn/categories/
网友评论