Android 指定Dex分包的Gradle插件

Android 的 multidex 可以使用maindexlist来指定哪些包的class放在第一个dex中,但却要我们自己手动指定,而且不能使用正则或者其他通配符指定,非常不方便。


Android的gradle构建方式给自定义构建带来很大的便利。你可以在自己的项目中增加一个buildSrc的module来专门处理一些构建时要用到的自定过程,可以使用groovy或者Java来编写。


本着对新事物探索的热爱,我也是一边学gradle一边试着用。从最开始在build.gradle中进行dex指定分包,到现在的可以配置化的Dex分包的gradle插件,也是走过一条长路。


===================================

更新:

1.5.9: 兼容一些古老的 gradle 和 android gradle plugin版本

1.5.8: 兼容gradle 3.2,修复当只使用support-split/support-keep时出现大量的额外类

1.5.7: 修复support-split/support-keep无效的bug

1.5.6:支持java 1.7,修复但只有keep选项时没有类被选中

1.5.5: 单独的maindexlist过滤设置

1.5.5.alpha: 实验性的支持 2.2.0 plugin

1.5.4: instant run 模式时自动禁用DexKnife

1.5.3: 增加跟踪日志,并在jarMerging为null时跳过处理

1.5.2: 修复include和exclude, 并支持过滤单个类(使用'.class'作为单个类的后缀)

1.5.1.exp 版本可以支持2.0以上的plugin

==============================


注意:DexKnife 本身只适用于将配置的通配符生成maindexlist,无法进行多个dex指定。

言归正传,指定dex分包插件为gradle-dexknife-plugin,使用他只需要做几件事:


1、com.android.tools.build:gradle 的版本可以是大于1.3.0的任何版本。

2.0.0以上的instant-run 与 multidex不兼容。在instant-run模式下,DexKnife会暂时自动禁用,在release打包时会自动启用。instant-run 采用新的打包模式,不会出现数量溢出的问题


2、在项目的build.gradle 增加依赖,我发把他发布到jcenter上了(先检查您的网络是否可达):

buildscript {
        ...

    dependencies {
        ....
        classpath 'com.ceabie.dextools:gradle-dexknife-plugin:1.5.9' 
    }
}


注意,请确保使用的gradle版本和android gradle plugin兼容,否则会出现同步错误,例如:
Gradle sync failed: Unable to load class 'com.android.builder.core.EvaluationErrorReporter'.


3、在App的module的目录下增加dexknife.txt文件,并编辑你需要的配置

使用 # 进行注释, 当行起始加上 #, 这行配置被禁用.

# 全局过滤, 如果没设置 -filter-suggest 并不会应用到 建议的maindexlist.
# 如果你想要某个包路径在maindex中,则使用 -keep 选项,即使他已经在分包的路径中.
-keep android.support.v4.view.**

# 这条配置可以指定这个包下类在第二dex中.
android.support.v?.**

# 使用.class后缀,代表单个类.
-keep android.support.v7.app.AppCompatDialogFragment.class

# 不包含Android gradle 插件自动生成的miandex列表.
-donot-use-suggest

# 将 全局过滤配置应用到 建议的maindexlist中, 但 -donot-use-suggest 要关闭.
-filter-suggest

# 不进行dex分包, 直到 dex 的id数量超过 65536.
-auto-maindex

# dex 扩展参数, 例如 --set-max-idx-number=50000
# 如果出现 DexException: Too many classes in --main-dex-list, main dex capacity exceeded,则需要调大数值
-dex-param --set-max-idx-number=50000

# 显示miandex的日志.
-log-mainlist

# 如果你只想过滤 建议的maindexlist, 使用 -suggest-split 和 -suggest-keep.
# 如果同时启用 -filter-suggest, 全局过滤会合并到它们中.
-suggest-split **.MainActivity2.class
-suggest-keep android.support.multidex.**


类路径的通配符与gradle其他用到的exclude 和include类似:

'*' 匹配任意数量的字符
'?' 匹配任意一个字符
'**' 匹配任何类路径和类
'.' 和 '/' 都可用来指定类的分割.
'.' 或者 '/' 的结尾会自动增加 '**'.

例如,android.*.v?.** ,android.support.v7 和v4下的所有类都被分到的第二个dex中。

注意: 如果你要过滤内部类, 使用$*,例如: SomeClass$*.class

具体参考:https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/util/PatternFilterable.html

4、在你的App的module中的build.gradle中加插件:

apply plugin: 'com.ceabie.dexnkife'

注意:要在 defaultConfig 或者 buildTypes中打开 multiDexEnabled true,否则不起作用。

最后,运行的app,分包的东西就交给DexKnife了。祝好运。

(dexknife只会在配置变动或者代码变动的时候才会处理)

项目地址:https://github.com/ceabie/DexKnifePlugin


插件调试:http://blog.csdn.net/ceabie/article/details/55271161


你可能感兴趣的:(android)