Android 插件化框架 DynamicLoadApk 源码分析

本文详细分析了DynamicLoadApk插件化框架的工作原理,包括扫描加载APK、创建AssetManager、DexClassLoader和Resource,以及启动插件Activity的过程。通过代理Activity和DLBasePluginActivity,实现了插件类的生命周期管理,避免了AMS的直接调度。

DynamicLoadApk 应该算是 Android 插件化诸多框架中资历比较老的一个了。它的项目地址在:dynamic-load-apk。该项目运行之后的效果是,使用 Gradle 编译出插件包和宿主包,都是以 APK 的形式。安装宿主包之后,通过 ADB 将插件包 push 到手机中。启动宿主包时,它会自动进行扫描将插件加载到应用中。点击插件之后,进入到插件的应用界面。

印象中最初接触的插件都是以单独安装的形式存在的,比如我可以做一个基础的应用,然后在该应用的基础上开发插件。用户可以对插件进行选择,然后下载并安装,以让自己的应用具有更丰富的功能。插件化也算是一种比较实用的技术,毕竟我们使用 Chrome 和 AS 的时候不是一样要加载插件。只是比较反感的是去修改底层的代码,容易给系统带来不稳定因素不说,技术到了一些人手里,你知道他用来干什么。插件化挺好,但真的要去推广这项技术,还是看好 Google 官方去进行规范。

技术要服务于产品,好的产品不一定要高超的技术,技术并不是最重要的,重要的是你究竟想要表达什么。这就像国内很多人只注重数理化,不注重人文学科。相比于国内的技术精英,我还是比较赞同 Google 站在整个生态的角度去考虑技术演进。前些日子社区里对插件化的讨论:移动开发的罗曼蒂克消亡史。好吧,我自己的理解是,这从来就不是什么罗曼蒂克。

DynamicLoadApk 插件化的实现方式还是挺有意思的,它使用纯 Java 实现,没有涉及 Native 层的代码,下面我理了下 DynamicLoadApk 的 Demo 程序的整个执行过程。后续的文章我们就围绕这张图进行,

DynamicLoadApk 的插件化执行过程

首先是扫描文件路径并加载 APK,这里需要解析 APK 文件的信息,它是本质上是通过 PMS 实现的;

    public DLPluginPackage loadApk(final String dexPath, boolean hasSoLib) {
   
   
        mFrom = DLConstants.FROM_EXTERNAL;

        // 通过 PMS 获取包信息,这里获取了 Activity 和 Service 的信息
        PackageInfo packageInfo = mContext.getPackageManager().getPackageArchiveInfo(dexPath,
                PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
        if (packageInfo == null) {
   
   
            return null;
        }

        DLPluginPackage pluginPackage = preparePluginEnv(packageInfo, dexPath);
        if (hasSoLib) {
   
   
            copySoLib(dexPath);
        }

        return pluginPackage;
    }

然后,它通过调用 preparePluginEnv() 方法来创建 AssetManager, DexClassLoader 和 Resource 等。我们的插件类加载各种资源和类的时候使用的就是这哥仨:

    private DLPluginPackage preparePluginEnv(PackageInfo packageInfo, String dexPath) {
   
   

        DLPluginPackage pluginPackage = mPackagesHolder.get(packageInfo.packageName);
        if (pluginPackage != null) {
   
   
            return pluginPackage;
        }
        DexClassLoader dexClassLoader = createDexClassLoader(dexPath);
        AssetManager assetManager = createAssetManager(dexPath);
        Resources resources = createResources(assetManager);
        // create pluginPackage
        pluginPackage = new DLPluginPackage(dexClassLoader, resources, packageInfo);
        mPackagesHolder.put(packageInfo.packageName, pluginPackage);
        return pluginPackage;
    }

    private DexClassLoader createDexClassLoader(String dexPath) {
   
   
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值