携程DynamicAPK插件化框架源码分析

携程DynamicAPK插件化框架源码分析


Author:莫川


插件核心思想

1.aapt的改造

分别对不同的插件项目分配不同的packageId,然后对各个插件的资源进行编译,生成R文件,然后与宿主项目的R文件进行id的合并。
要求:由于最终会将所有的资源文件id进行合并,因此,所有的资源名称均不能相同。

2.运行ClassLoader加载各Bundle

和MultiDex的思路是一样的,所有的插件都被加载到同一个ClassLoader当中,因此,不同插件中的Class必须保持包名和类名的唯一。否则,加载过的类不会再次被加载。
优缺点:各个Bundle之间完全可以相互调用,但是这也造成了各个Bundle之间ClassLoader的非隔离性。并且随着数组的加长,每次findClass的时间会变长,对性能照成一定长度的影响。
让我们在熟悉一下这张图:
multidex

在DynamicAPK框架中,每个Bundle被加载到ClassLoader的调用栈如下:
Bundle的Application:BundleBaseApplication
->BundleBaseApplication(onCreate)
->BundleCore(run)
->BundleImpl(optDexFile)
->BundleArchiveRevision(optDexFile)
->BundlePathLoader(installBundleDexs)
->…

如下图所示:
class

3.热修复

由于所有的插件都被加载到同一个ClassLoader当中,因为,热修复的方案都是从dexElements数组的顺序入手,修改expandFieldArray方法的实现,将修复的类放到dexElements的前方。核心代码如下(详见BundlePathLoader):


 private static void expandFieldArray(Object instance, String fieldName,
                                         Object[] extraElements,boolean isHotFix) throws NoSuchFieldException, IllegalArgumentException,
            IllegalAccessException {
        synchronized (BundlePathLoader.class) {
            Field jlrField = findField(instance, fieldName);
            Object[] original = (Object[]) jlrField.get(instance);
            Object[] combined = (Object[]) Array.newInstance(
                    original.getClass().getComponentType(), original.length + extraElements.length);
            if(isHotFix) {
                System.arraycopy(extraElements, 0, combined, 0, extraElements.length);
                System.arraycopy(original, 0, combined, extraElements.length, original.length);
            }else {
                System.arraycopy(original, 0, combined, 0, original.length);
                System.arraycopy(extraElements, 0, combined, original.length, extraElements.length);
            }
            jlrField.set(instance, combined);
        }
    }

调用的关键代码如下(HotPatchItem.class):

   public void optDexFile() 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值