插件化知識梳理(5) Small 框架之如何不將插件打包到宿主中

1、前言

在前面的例子當中,咱們都是把插件預置在Apk當中一塊兒安裝的,如 插件化知識梳理(4) - Small 框架之如何實現插件更新 所示,咱們初始時候會將表明插件的so文件放置在jniLibs/armeabi目錄下。 java

那麼若是咱們將不是很重要的插件放在服務器上,當應用啓動以後判斷須要該插件,而後再從服務器上下載,將可以有效減少初始時候安裝包的體積。

下面,咱們就來演示一下如何從外部加載插件。bash

2、示例

加載插件部分的源碼位於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();
        }
    }
複製代碼

更多文章,歡迎訪問個人 Android 知識梳理系列:

相關文章
相關標籤/搜索