一个快速将指定class打入maindex的插件

项目地址:https://github.com/JeasonWong/MainDexWrapper

使用场景

场景很多,先说两种:

  • 当使用了multidex进行分包后,为了优化app首次启动

  • 需要代理Application时,如InstantRun和其他hotfix框架

如何使用

官方方案

其实官方支持两种方式将指定class打入maindex:

  • multiDexKeepProguard file(‘./maindex-rules.pro’)
  • multiDexKeepFile file(‘./maindex.txt’)

关于这两种方案的使用我就不赘述了。

MainDexWrapper

配置

MainDexWrapper 支持两种方式,其中一种和官方的multiDexKeepProguard file('./maindex-rules.pro')相似。

首先在根build.gradle将插件依赖好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
buildscript {
repositories {
maven {
url 'https://dl.bintray.com/wangyuwei/maven'
}
}
dependencies {
classpath 'me.wangyuwei:maindexwrapper-plugin:1.0.0'
}
}
allprojects {
repositories {
maven {
url 'https://dl.bintray.com/wangyuwei/maven'
}
}
}

然后在app的build.gradle使用插件:

1
2
3
apply plugin: 'me.wangyuwei.maindexwrapper'
compile 'me.wangyuwei:maindexwrapper-annotations:1.0.0'
使用

两种方式:

  • 书写keep-rules
  • 给指定的class加上 @KeepMainDex 注解

1、书写keep-rules:

1
2
#
#-keep class me.wangyuwei.maindexwrapper.demo.Demo {*;}

就像配置混淆方式一样,把你需要打入maindex的class的规则写好。

2、给指定的class加上 @KeepMainDex 注解

1
2
3
4
5
6
7
8
9
10
import me.wangyuwei.maindexwrapper.annotations.KeepMainDex;
@KeepMainDex
public class Demo {
public class InnerClass {
}
}

就像混淆支持 @keep 注解一样,使用也很简单。

原理

其实很简单。

一句话说明就是在执行multidexTask前将我们的 keep-rules 加入到 /intermediates/multi-dex/${variant.dirName}/manifest_keep.txt 里。

manifest_keep.txt 是multidex分包时一个很重要的文件,这里keep住的class会被打入到maindex。

那么目前插件实现的两种方案就比较好下手了:

第一种是将开发人员书写的 maindex-rules.pro 里的内容直接copy到 manifest_keep.txt 里;

第二种用注解的方式直接遍历生成dex前的classes,含有 @KeepMainDex注解的先收集起来,然后再和前者一样copy到 manifest_keep.txt 里,我这里使用的 ASM 遍历的classes,需要注意的是需要将ClassName里的 "/"替换成".",别的就很简单了。

尾语

插件整个下来比较简单,当做练手也是可以的。