在前面的例子當中,咱們都是把插件預置在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();
}
}
複製代碼