插件化知识梳理(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 知识梳理系列:

相关文章
相关标签/搜索