在前面的例子当中,咱们都是把插件预置在Apk
当中一块儿安装的,如 插件化知识梳理(4) - Small 框架之如何实现插件更新 所示,咱们初始时候会将表明插件的so
文件放置在jniLibs/armeabi
目录下。 java
下面,咱们就来演示一下如何从外部加载插件。bash
加载插件部分的源码位于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
文件拷贝到外部存储中,从外部存储读取的过程就至关因而网络下载的过程:app
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();
}
}
复制代码