首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MultiDex(三)之异步加载优化

MultiDex(三)之异步加载优化

作者头像
用户2898788
发布2018-08-21 10:11:16
1.2K0
发布2018-08-21 10:11:16
举报
文章被收录于专栏:双十二技术哥双十二技术哥

一、前言

在上一篇文章《Multidex(二)之Dex预加载优化》中我们提到主进程中直接开启一个子线程执行MultiDex的工作确实可以避免ANR的问题,然而此时主进程中调用到的类,可能会因为SecondaryDex的优化尚未完成或者没有被加入到ClassLoader中而导致画面太美不敢看的ClassNotFoundException。如何是好?明知山有虎,偏往虎山行!

本文就带你实战MultiDex的异步加载优化。

二、分析

既然我们要做的是异步加载优化,那毋庸置疑MultiDex.install是要放在子线程了,这步简单。接下来我们分析下ClassNotFoundException的原因,在非主Dex没有被优化、加载到ClassLoader之前引用到了其中的Class,肯定找不到秒秒钟异常给你看。那问题就转换成了下面这两个

  • 如何保证程序的入口类以及入口类的引用类都在主Dex?
  • 以及在非主Dex类加载的时候如何进行判断干预?

问题一:在保证主Dex不被撑爆的前提下,我们可以定义一个Task对Gradle打包的流程进行自定义,将程序的入口类以及入口类的引用类都放到主Dex中。

问题二:在非主Dex类加载的时候进行校验,当异步优化还没完成的时候返回或者加载一个Loading的界面提示用户等待。如何对一个具体的类进行校验呢?看起来比较复杂。换个思路,我们把基类都放到主Dex中,保证非主Dex加载的时候都是调用四大组件,然后进行Hook。这样非主Dex被调用的时候都是通过四大组件来调用的,而基础类都在主Dex已经提前被加载,可以放心调用。

三、上代码,Show The Code

Application异步执行Multidex.install;

干预打包流程,保证入口类以及入口类的引用类都放在主Dex中。

如何对四大组件进行Hook?此处分析Activity为例。

startActivty的时候最终都会调用到Instrumentation.execStartActivity方法。

ContextImpl.java

Activity.java

追踪Instrumentation对象的来路,是在ActivityThread里的performLaunchActivity方法。那我们就对Instrumentation进行Hook。

此处重写了Instrumentation的两个方法,newActivity与execStartActivity,这两个方法都可以实现我们的需求,具体用哪一个呢?推荐newActivity,此处创建Activity对象,执行顺序靠前。

四、看效果

反编译查看方法数以及keep_in_main_dex.txt里的文件是否在主Dex中。

单Dex方法数不超过设置的48k

在子线程中Sleep若干秒,快速点击非主Dex中的Activity,制造现场。可以看到打印出来的Log以及,显示的Activity也是LoadDexActivity,实现了拦截

五、问题

1、这个方案的缺点?

通过以上分析及代码实践,可以看到,这个方案虽然实现了Dex在主进程的子线程中的加载,但是改动量极大;

  • 需要对Gradle打包的过程进行定制,将入口类以及入口类的引用类都放的keep_in_main_dex.txt,这个过程需要用脚本实现,并且经常性的更新、维护;
  • 不同版本Gradle的Api可能会有变化,因此需要额外处理;
  • 本文分析的是对Activity的Hook,而原则上四大组件都需要Hook,时间成本上肯定更长;
  • 还有其他类如记录真实跳转Activity,在异步处理完毕之后跳往真实Activity的逻辑。

2、推荐方案?

鉴于问题1中描述的缺点,所以更推荐上一篇文章《Multidex(二)之Dex预加载优化》的方案,使用方便简单。

以上就是MultiDex系列文章的全部三篇,对MultiDex的原理及优化方案进行了分析。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 双十二技术哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档