抖音BoostMultiDex优化实践:Android低版本上APP首次启动时间减少80%

最后,APP 把这些DexFile对象都添加到PathClassLoaderpathList里面,就可以让 APP 在运行期间,通过ClassLoader加载使用到这些 DEX 中的类。

在这整个过程中,生成 ZIP 和 ODEX 文件的过程都是比较耗时的,如果一个 APP 中有很多个 Secondary DEX 文件,就会加剧这一问题。尤其是生成 ODEX 的过程,Dalvik 虚拟机会把 DEX 格式的文件进行遍历扫描和优化重写处理,从而转换为 ODEX 文件,这就是其中最大的耗时瓶颈。

普遍采用的优化方式


目前业界已经有了一些对 MultiDex 进行优化的方法,我们先来看下大家通常是怎么优化这一过程的。

异步化加载

把启动阶段要使用的类尽可能多地打包到主 Dex 里面,尽量多地不依赖 Secondary DEX 来跑业务代码。然后异步调用MultiDex.install,而在后续某个时间点需要用到 Secondary DEX 的时候,如果 MultiDex 还没执行完,就停下来同步等待它完成再继续执行后续的代码。

这样确实可以在 install 的同时往下执行部分代码,而不至于被完全堵住。然而要做到这点,必须首先梳理好启动逻辑的代码,明确知道哪些是可以并行执行的。另外,由于主 Dex 能放的代码本身就比较有限,业务在启动阶段如果有太多依赖,就不能完全放入主 Dex 里面,因此就需要合理地剥离依赖。

因此现实情况下这个方案效果比较有限,如果启动阶段牵扯了太多业务逻辑,很可能并行执行不了太多代码,就很快又被 install 堵住了。

模块懒加载

这个方案最早见于美团的文章,可以说是前一个方案的升级版。

它也是做异步 DEX 加载,不过不同之处在于,在编译期间就需要对 DEX 按模块进行拆分。

一般是把一级界面的 Activity、Service、Receiver、Provider 涉及到的代码都放到第一个 DEX 中,而把二级、三级页面的 Activity 以及非高频界面的代码放到了 Secondary DEX 中。

当后面需要执行某个模块的时候,先判断这个模块的 Class 是否已经加载完成,如果没有完成,就等待 install 完成后再继续执行。

可见,这个方案对业务的改造程度相当巨大,而且已经有了一些插件化框架的雏形。另外,想要做到能对模块的 Class 的加载情况进行判断,还得通过反射 ActivityThread 注入自己的 Instrumentation,在执行 Activity 之前插入自己的判断逻辑。这也会相应地引入机型兼容性问题。

多线程加载

原生的 MultiDex 是顺序依次对每个 DEX 文件做 ODEX 优化的。而多线程的思路是,把每个 DEX 分别用各自线程做 OPT。

这么乍看起来,似乎是能够并行地做 ODEX 来起到优化效果。然而我们项目中一共有 6 Android开源项目《ali1024.coding.net/public/P7/Android/git》 个 Secondary DEX 文件,实测发现,这种方式几乎没有优化效果。原因可能是 ODEX 本身其实是重度 I/O 类型的操作,对于并发而言,多个线程同时进行 I/O 操作并不能带来明显收益,并且多线程切换本身也会带来一定损耗。

后台进程加载

这个方案主要是防止主进程做 ODEX 太久导致 ANR。当点击 APP 的时候,先单独启动了一个非主进程来先做 ODEX,等非主进程做完 ODEX 后再叫起主进程,这样主进程起来直接取得做好的 ODEX 就可以直接执行。不过,这只是规避了主进程 ANR 的问题,第一次启动的整体等待时间并没有减少。

一个更彻底的优化方案


上述几个方案,在各个层面都尝试做了优化,然而仔细分析便会发现,它们都没有触及这个问题中根本,也就是就MultiDex.install操作本身。

MultiDex.in

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值