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

一、背景

随着京东金融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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 176,084评论 25 709
  • 今天又是异常的热。 昨日之行换来今日的疲惫,娘三仿佛一下子变成了非洲人。休息半日,稍微好点。 下午没事,约上三俩好...
    吕玥妈咪阅读 1,432评论 0 4
  • 夜又来了,以它优雅的姿态,伴着幽寂的旋律。 这是我最喜欢的时刻,剔除一切浮华和喧嚣,唯留内心的平静,倾听着灯的倾述...
    悦者阅读 3,395评论 6 6
  • 1 我叫莫子鱼,是一只狗鱼,至今1000岁,热爱寒冷和肉食。 人类经常说,我们最多能够活到两百多岁,其实很多狗鱼根...
    大钱小胖阅读 4,353评论 23 11
  • 今天和一位拍纪录片师兄聊他的路演项目,在定位之外,扩展到资源整合、传播和资金的统筹,最后还是回到众筹的思维是最好的...
    韧性十足的牛皮糖阅读 2,454评论 0 0

友情链接更多精彩内容