相關(guān)閱讀
插件化知識(shí)梳理(1) - Small 框架之如何引入應(yīng)用插件
插件化知識(shí)梳理(2) - Small 框架之如何引入公共庫(kù)插件
插件化知識(shí)梳理(3) - Small 框架之宿主分身
插件化知識(shí)梳理(4) - Small 框架之如何實(shí)現(xiàn)插件更新
插件化知識(shí)梳理(5) - Small 框架之如何不將插件打包到宿主中
插件化知識(shí)梳理(6) - Small 源碼分析之 Hook 原理
插件化知識(shí)梳理(7) - 類的動(dòng)態(tài)加載入門
插件化知識(shí)梳理(8) - 類的動(dòng)態(tài)加載源碼分析
插件化知識(shí)梳理(9) - 資源的動(dòng)態(tài)加載示例及源碼分析
插件化知識(shí)梳理(10) - Service 插件化實(shí)現(xiàn)及原理
一柳譬、前言
在前面的例子當(dāng)中邮弹,我們都是把插件預(yù)置在Apk
當(dāng)中一起安裝的,如 插件化知識(shí)梳理(4) - Small 框架之如何實(shí)現(xiàn)插件更新 所示瞧筛,我們初始時(shí)候會(huì)將代表插件的so
文件放置在jniLibs/armeabi
目錄下。
那么如果我們將不是很重要的插件放在服務(wù)器上,當(dāng)應(yīng)用啟動(dòng)之后判斷需要該插件,然后再?gòu)姆?wù)器上下載胁黑,將能夠有效減小初始時(shí)候安裝包的體積。
下面州泊,我們就來(lái)演示一下如何從外部加載插件丧蘸。
二、示例
加載插件部分的源碼位于Bundle.java
中:
可以看到遥皂,加載插件有兩種方式力喷,它們是根據(jù)
Small.isLoadFromAssets
來(lái)區(qū)分:
- 如果該標(biāo)志位為真,那么讀取
/data/data/{host_pkg_name}/small_base/
下的插件演训,并且包名和插件的對(duì)應(yīng)關(guān)系為:pkg_name -> {pkg_name}.apk
- 如果該標(biāo)志位為假弟孟,那么讀取
nativeLibraryDir
目錄下的so
,并且包名和插件的對(duì)應(yīng)關(guān)系為:pkg_name -> lib{pkg_name}.so
样悟,也就是我們之前一直演示的方式拂募。
通過(guò)這段源碼庭猩,那么如何實(shí)現(xiàn)加載外部插件就有思路了:
- 刪除調(diào)
jniLIbs/armeabi
下的so
文件 - 通過(guò)
Small.setLoadFromAssets
方法將標(biāo)志位設(shè)為true
- 從網(wǎng)絡(luò)上獲取插件,創(chuàng)建
/data/data/{host_pkg_name}/small_base/{pkg_name}.apk
陈症,通過(guò)文件流的形式將下載下來(lái)的插件寫入到.apk
當(dāng)中蔼水。
這里因?yàn)闆](méi)有服務(wù)器,所以我們把預(yù)先編譯好的插件.so
文件拷貝到外部存儲(chǔ)中录肯,從外部存儲(chǔ)讀取的過(guò)程就相當(dāng)于是網(wǎng)絡(luò)下載的過(guò)程:
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的內(nèi)容寫入到.apk當(dāng)中。
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
更多文章论咏,歡迎訪問(wèn)我的 Android 知識(shí)梳理系列:
- Android 知識(shí)梳理目錄:http://www.reibang.com/p/fd82d18994ce
- 個(gè)人主頁(yè):http://lizejun.cn
- 個(gè)人知識(shí)總結(jié)目錄:http://lizejun.cn/categories/