京东金融Dex拆分工具Scalpel技术揭秘

2017-09-06  本文已影响0人  c61e39f6e84d

一、背景

随着京东金融Android项目功能的不断增加,代码数量也随之急剧增加,虽然使用了MultiDex的处理,但是在不断的加入更多类之后,我们依旧面临着以下挑战:

问题1:编译时出现错误com.Android.dex.DexException: Toomanyclasses in --main-dex-list, main dex capacity exceeded

产生原因:主dex超过最大方法数限制。一个DEX文件中method个数采用使用原生类型short来索引文件中的方法,也就是4个字节共计最多表达65536个method,field/class的个数也均有此限制。

问题2:低端机上黑屏或白屏,冷启动速度过慢

产生原因:dex加载耗时。在项目中使用Google提供的MultiDex后dex拆分为多个,而Android运行时只默认加载classes.dex这个文件(即主dex)。其他dex会在Application.attachBaseContext中使用Multidex.install进行解压缩和加载。Multidex.install是一个耗时大户,会堵塞主线程,从而使主线程无法响应Activity的创建和初始化。而5.0及以上版本已经不存在这个问题,是由于ART模式的存在,app第一次安装之后会进行一次预编译(pre-compilation),如果这时候发现了classes(..N).dex文件就会将他们最终合成为一个.oat,并在app启动时一次性加载。

二、解决方案

面向问题1的解决方案:只要保证主dex中的方法数少于65536个,在gradle编译脚本中加入dx.additionalParameters +='--set-max-idx-number=xxx'参数即可解决。

面向问题2的解决方案:首先想到的就是异步加载,但如果此时classloader需要加载某个类,而这个类却没有在主dex中,就会出现ClassNotfindException的异常崩溃,所以其实解决这两个问题的根本方法是指定打包时将哪些类放到主dex中。

三、Scalpel介绍

Scalpel是京东金融客户端研发的业界首个可以干预主dex生成的工具,可以根据配置文件指定某些符合规则的、及其必要的依赖类放到主dex中。除了根据配置文件,Scalpel还会自动分析你的项目,把一些必须放入主dex中的类找到并放进去。

在使用MultiDex时,BuildTool会自动把代码拆成多个dex包,并通过扫描把Application , Activity , Service , ContentProvider和BrocastReceiver以及必要依赖类放进主dex包中,以下是Android的打包流程图:

为了实现指定主dex中的类,我们在生成dex文件这一步时,使用gradle自定义Task来干预dex的生成过程,由于人工分析class有着不可维护性和高风险性,Scalpel则完美解决了对人工的依赖,从而极大的提高了生产效率。

具体用法(写法和混淆文件类似):

1.工程根目录gradle.build中添加以下内容

repositories {

jcenter();

maven {

url "http://dl.bintray.com/gokuo/maven"

}

}

dependencies{

classpath 'com.jd.jrapp.plugin:Scalpel:1.0.1'

}

2:项目目录下build.gradle中添加apply plugin: 'com.jd.jrapp.scalpel'

3:项目目录下添加scalpel_rule.pro规则文件,并填写以下内容

如:

(1)把supportv4包下所有的类和相关必要依赖类都打进主dex

-keep class android.support.v4.**{*;}

(2)把Fragment类打进主dex

-keep class android.support.v4.app.Fragment

(3)把Fragment类和相关必要依赖类打入主dex

-keep class android.support.v4.app.Fragment{*;}

(4)把所有Fragment的子类打入主dex

-keep class * extends android.support.v4.app.Fragment

四、实现原理

请参见源码:https://github.com/gokuo/scalpel

五、提供支持

您如果有任何问题,可以在开源项目中提交bug报告,也可以发送邮件至 gaokuo@jd.com

上一篇下一篇

猜你喜欢

热点阅读