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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

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