美文网首页
京东金融Dex拆分工具Scalpel技术揭秘

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

作者: 一把菜刀闹革命 | 来源:发表于2017-09-06 18:35 被阅读0次

    一、背景

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

    相关文章

      网友评论

          本文标题:京东金融Dex拆分工具Scalpel技术揭秘

          本文链接:https://www.haomeiwen.com/subject/fbnhdxtx.html