前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Multidex(二)之Dex预加载优化

Multidex(二)之Dex预加载优化

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

一、前言

Multidex(一)之源码解析中我们介绍到MultiDex极有可能出现ANR(Application No Response)的问题,秒秒钟卡死我们的应用,用户肯定忍不了要怒卸载啊!作为追(被)求(逼)完(无)美(耐)的程序员哥哥,我们怎能作壁上观?Google不做好的事情,我们就自己扛起来!那么如何对MultiDex这个方案做优化让它变成好同志呢?

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

二、分析

Multidex(一)之源码解析中分析过MultiDex第一次加载出现ANR的原因是因为提取Dex以及DexOpt这两个过程都是耗时的操作,而且他们还都发生在主进程。稍等:主进程,ANR,脑袋里好像闪现一道灵光,既然在主进程执行会产生ANR,那能不能换个进程执行呢?橘生淮南则为橘,生于淮北则为枳;换个进程说不定就有突破点。说干就干,凭借程序员机智的大脑,分毫之间,一个优化方案的雏形已经了然于胸:App第一次启动时单独开一个额外优化的进程率先进行Dex提取以及DexOpt的操作,与此同时主进程在后台等待,优化的进程执行完毕之后通知主进程继续往下执行,主进程在执行MultiDex.install时发现已经是提前优化好了Dex,直接执行,非常快,毫秒级别,不会造成卡顿,愉快的往下继续执行。

三、优化方案工作流程图

四、代码实战

然后在PreLoadDexActivity中执行优化的操作,完成后修改标示;

在AndroidManifest中配置:

运行看一下效果:

可以通过Log看到,在优化进程中Dex的提取以及Dexopt的操作耗时近4秒,而在主进程的第二次执行则耗时16毫秒,耗时发生在优化进程中的线程中,主进程实际执行MultiDex.install的时候耗时极其短暂;再也不会出现ANR的困扰了。

  • 第一次打开App,会出现PreLoadDexActivity,略显突兀,可以再应用的闪屏页加上这段逻辑,根据标示判断究竟执行正常逻辑还是优化的逻辑。
  • 关于SharedPreferences进程间不安全的问题:此处的使用只是单向的读写,因而不会有这个场景。

五、问题

1、为什么执行优化操作的时候判断只有在主进程以及SDK版本5.0以下才执行呢?

如果App是多进程架构的话,Application会执行多次,这个优化过程无需执行多次;而在SDK版本5.0及以上,默认使用ART虚拟机,与Dalvik的区别在于安装时已经将全部的Class.dex转换为了oat文件,优化过程在安装时已经完成;因此无需执行。

2、为什么主进程此时不会ANR?

回忆下ANR的发生场景:Service、BroadCastReceiver、ContentProvider的TimeOut;输入事件的TimeOut等。当出现ANR时,都会最终调用到AMS的appNotResponding()方法。

因为主进程此时已经进入后台,不响应Android屏幕事件。同时也不存在以上发生ANR的场景,因此主进程在后台Sleep,不会产生ANR。

3、在优化的进程中只是开启了一个线程提前做了MultiDex的工作,那为什么不直接在主进程中开启一个子线程做同样工作呢?

Good Question,不愧是善于思考的程序猿!在主进程中直接开启一个子线程确实是可以避免ANR的问题,但是有没有想到,此时主进程中调用到的类,可能会因为SecondaryDex的优化尚未完成或者没有被加入到ClassLoader中而导致画面太美不敢看的ClassNotFoundException。

那是不是就宣判了这个想法的死刑呢?No,No,No,程序猿就是为了解决挑战而生的,异步加载确实是个正常又合理的想法,那这个想法怎么落地呢?

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

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

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

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

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