Android Multidex 的问题优化

rkvp5357 7年前
   <h2><strong>降低启动速度的问题</strong></h2>    <p>文章中提到的一点,在 Android 设备 4.4 及其之前的版本,当开启 Multidex 的时候,启动速度会延长 15% 。而 5.0及以上的设备因使用 ART 的方式,其默认支持多 dex 的加载。</p>    <h2><strong>NoClassDefFoundError 的问题</strong></h2>    <ul>     <li>查看加载的类问题 在目录 [buildDir]/intermediates/multi-dex/[buildType]/maindexlist.txt 中可查看在主 dex 文件中的类,(但并不是 100% 准确,可能会丢失一些类)</li>     <li>解决办法:配置一个新的 multidex.keep 文件,用来指定在 mainDex 中包含的类。通过配置 gradle 文件,指定 gradle 打包过程中,执行 dex 生成时的 keep 文件追加。具体实施是创建一个新的 task,使用 finalizedBy 来指定在 create**MainDexClassList 任务之后执行。另外还需要指定 dx 执行时,添加 —minimal-main-dex 选项,来使 maindex 最小化。</li>    </ul>    <h2><strong>如何判断 App 启动过程中哪些类是需要加载的呢?</strong></h2>    <p>通过使用类加载 ClassLoader 中,其提供了方法 findLoadedClass。这个方法的作用是用来判断某个类是否被加载,所以文章中使用的技巧就是通过读在 second dex files 中的类,来判断主 dex 是否加载到。若是加载到,则我们就需要将这个类添加至 main dex 来提高 App 的启动速度。</p>    <h2><strong>解决与建议</strong></h2>    <p>出现 65k 的问题时候,通过其他方式(重构、优化第三方 SDK的使用)来尽量避免使用 Multidex;若是不可避免地使用,需要对 Multidex 的方式进行优化来使用,来尽量提高我们 App 的启动速度。</p>    <h3><strong>延迟加载</strong></h3>    <p>对纯 java 文件,可以将其单独打成一个 dex,利用 Multidex 加载的原理,在当我们使用到相应 java 文件的时候,再加载这个 dex,来执行相应代码的调用。(方案有些不成熟,不支持涉及到资源文件的情况。)</p>    <h2><strong>其他</strong></h2>    <h3><strong>1. 工具 ClassShark</strong></h3>    <p>在评论区,提到的一个软件 android-classyshark ,可以帮我们更加容易分析 APK、dex、jar 中的使用内容,(不再通过 dex2jar, jd-gui等工具来查看)能够对 apk 中的内容一目了然, 功能非常强大。</p>    <p>在 Android Studio 2.2 之后的版本,其已经支持了对 apk 的分析,可以直接点击进行查看。</p>    <h3><strong>2. dex2oat 与 dexopt</strong></h3>    <p>评论中关于 5.0及以上不受影响的讨论,主要原因是因为 5.0 采用了 ART 的编译方式,其是在 app 安装的时候执行的,期间对 dex 文件采用了 dex2oat 的执行过程,来对 dex 文件进行优化。而 5.0 之前的设备是没有这一步,其采用的 dexopt 的过程,并处理的是单个 dex 文件,这样也会影响了 multidex 的启动速度,但是这个是每次打开 app 都会进行的,并不是安装时执行的。</p>    <p>作者的关注点是在每次 App 打开的过程中, Multidex 带来的影响,所以这个讨论在这里并不是与主题太多相关,但是我们还是又必要了解一下的。</p>    <h2><strong>参考资料</strong></h2>    <ul>     <li><a href="/misc/goto?guid=4959723298434108108" rel="nofollow,noindex">Android’s multidex slows down app startup</a></li>     <li><a href="/misc/goto?guid=4959723298514805767" rel="nofollow,noindex">multidex-sample</a></li>     <li><a href="/misc/goto?guid=4959723298601462786" rel="nofollow,noindex">Lazy Loading Dex files</a></li>    </ul>    <p> </p>    <p>来自:http://alighters.com/blog/2016/11/01/multidex-problems/</p>    <p> </p>