Skip to content

Commit b3e8eac

Browse files
authored
Update README.md
1 parent 83f7871 commit b3e8eac

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

README.md

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ protected void attachBaseContext(Context base) {
2323
```
2424

2525
###坑2:Too many classes in –main-dex-list ,what?
26-
**原因:**通过上面的官方分包,已经把原Dex分为1主Dex加多从Dex,主Dex保留4大组件,Application,Annotation,multidex等及其必要的直接依赖。由于我们方法数已达到16W之巨,上百个Activity,所以成功的把主Dex又撑爆了
26+
**原因:**通过上面的官方分包,已经把原Dex分为1主Dex加多从Dex。主Dex包含所有4大组件,Application,Annotation,multidex等及其必要的直接依赖。由于我们方法数已达到16W之巨,上百个Activity全部塞进主Dex,又成功的把主Dex撑爆了
2727

2828
**解决:**
2929
gradle
@@ -42,37 +42,36 @@ afterEvaluate {
4242
参考=>[Android Dex分包之旅](http://yydcdut.com/2016/03/20/split-dex/index.html)
4343

4444
###坑3:gradle 1.5.0之后不支持这种写法 ,what the fuck?
45-
**原因:**官方解释Gralde`1.5.0`以上已经将(jacoco, progard, multi-dex)统一移到[Transform API](http://tools.android.com/tech-docs/new-build-system/transform-api)里,然而Transform API并没有想象的那么简单好用,最后翻遍Google终于找到一个兼容Gradle `1.5.0`以上的分包插件[DexKnifePlugin](https://github.com/ceabie/DexKnifePlugin)
46-
参考=>这篇[Android 热修复使用Gradle Plugin1.5改造Nuwa插件](http://blog.csdn.net/sbsujjbcy/article/details/50839263)比较好的介绍了Transform API的使用。
45+
**原因:**官方解释Gralde`1.5.0`以上已经将(jacoco, progard, multi-dex)统一移到[Transform API](http://tools.android.com/tech-docs/new-build-system/transform-api)里,然而Transform API并没有想象的那么简单好用,翻遍Google终于找到一个兼容Gradle `1.5.0`以上的分包插件[DexKnifePlugin](https://github.com/ceabie/DexKnifePlugin)
46+
扩展=>这篇[Android 热修复使用Gradle Plugin1.5改造Nuwa插件](http://blog.csdn.net/sbsujjbcy/article/details/50839263)比较好的介绍了Transform API的使用。
4747

4848
###坑4:NoClassDefFoundError ,are you kiding me?
4949
**原因:**通过插件手动指定main dex中要保留的类,虽然分包成功,但是main dex中的类及其直接引用类很难通过手动的方式指定。
5050

5151
**解决方式:**
52-
看了[美团Android DEX自动拆包及动态加载简介](http://tech.meituan.com/mt-android-auto-split-dex.html),他们是通过编写了一个能够自动分析Class依赖的脚本去算出主Dex需要包含的所有必要依赖。看来依赖脚本是跑不掉了
52+
[美团Android DEX自动拆包及动态加载简介](http://tech.meituan.com/mt-android-auto-split-dex.html),他们是通过编写了一个能够自动分析Class依赖的脚本去算出主Dex需要包含的所有必要依赖。看来写脚本是跑不掉了
5353

5454
###坑5:自定义脚本 ,read the fuck source!
55-
**问题一:**放进主Dex里应该有哪些类,规则是什么
56-
查看sdk\build-tools\platform-version\mainDexClasses.rules发现应该放进主Dex类有Instrumentation,Application,Activity,Service,ContentProvider,BroadcastReceiver,BackupAgent的所有子类。
55+
**问题一:**哪些类是需要放入主Dex中
56+
查看sdk\build-tools\platform-version\mainDexClasses.rules发现放入主Dex相关类有Instrumentation,Application,Activity,Service,ContentProvider,BroadcastReceiver,BackupAgent的所有子类。
5757

58-
**问题二:**gradle是在哪里计算出主Dex依赖
58+
**问题二:**gradle是在哪里算出主Dex依赖
5959
查看Gradle编译任务发现有如下3个编译任务:
6060
<img src="png/2.png" height= "100" width="400">
6161

62-
运行collect任务,发现会在build/multi-dex目录下单独生成manifest_keep.txt文件,该文件其实就是通过上述规则扫描AndroidManifest生成。manifest_keep.txt保留的是所有需要放入主Dex里的类。还没完,接下来transformClassesWithMultidexlist任务会根据manifest_keep.txt生成必要依赖列表maindexlist.txt,这里面所有类才是真正放入主Dex里的。bingo,思路已经非常清晰,我们只需要控制manifest_keep.txt的类,依赖关系由系统帮我们生成,即可控制主Dex大小和方法数,安全可靠
62+
运行collect任务,发现会在build/multi-dex目录下单独生成`manifest_keep.txt`文件,该文件其实就是通过上述规则扫描`AndroidManifest`生成。`manifest_keep.txt`保留的是所有需要放入主Dex里的类。还没完,接下来`transformClassesWithMultidexlist`任务会根据`manifest_keep.txt`生成必要依赖列表`maindexlist.txt`,这里面所有类才是真正放入主Dex里的。bingo,现在非常清楚,我们只需要控制进入manifest_keep.txt中的类即可,最终其类的依赖关系由系统帮我们生成即可,安全绿色可靠
6363

6464
<img src="png/3.png" height = "200" width="500">
6565
<img src="png/4.png" height = "200" width="500">
6666

67-
**问题三:**在哪里控制maindexlist.txt的大小?
68-
由问题一我们知道生成manifest_keep.txt的规则,对于绝大部分工程来说,manifest_keep.txt中80%是Activity,其实我们只需要在主Dex中保留首页 Activity、Laucher Activity 、欢迎页的 Activity 等启动时必要的Activity就OK了。
69-
67+
**问题三:**在哪里控制`maindexlist.txt`的大小?
68+
由问题一我们知道生成`manifest_keep.txt`的规则,对于绝大部分工程来说,`manifest_keep.txt`中80%是Activity,其实我们并不需要把全部的Activity放入主Dex,只需要保留必要的Activity即可,如首页 Activity、Laucher Activity 、欢迎页的 Activity 等启动时必要的Activity就OK了。
7069

7170
下图是Gradle的工作流程:
7271
<img src="png/1.png" width="800">
7372
来源:[深入理解Android之Gradle](http://blog.csdn.net/innost/article/details/48228651)
7473

75-
我们只需要在完成任务向量图之后,执行任务之前Hook一下collect任务,做下activity过滤就OK了,添加Gradle:
74+
我们只需要在完成任务向量图之后,执行任务之前Hook一下collect任务,过滤掉不必要的activity就OK了。添加Gradle:
7675
```
7776
//需要加入主dex的Activity列表
7877
def mainDexListActivity = ['WelcomeActivity', 'MainFunctionActivity']
@@ -97,11 +96,11 @@ afterEvaluate {
9796
```
9897

9998
###坑6:主dex依然爆表,shit again!
100-
其实上面那段脚本已经成功筛选出我们想要的主Dex的manifest_keep和maindexlist,只是不知道为什么还是把所有类打进主Dex。这个时候就需要跟[DexKnifePlugin](https://github.com/ceabie/DexKnifePlugin)插件配合使用,首先在gradle中加上上述脚本,然后使用插件时在配置文件里加上 `-split **.**``#-donot-use-suggest`
99+
其实上面那段脚本已经成功筛选出我们想要放入主Dex的`manifest_keep列表``maindexlist列表`,但是在打包的时候还是把所有类打进主Dex(已无语)。这个时候就需要跟[DexKnifePlugin](https://github.com/ceabie/DexKnifePlugin)插件配合使用,首先在gradle中加上上述脚本,然后使用插件时在配置文件中加上 `-split **.**``#-donot-use-suggest`。DexKnifePlugin插件运行原理很简单,在生成Dex任务之前首先读取自己的配置文件(同时附加上我们前面通过Gradle脚本生成的`maindexlist`),然后扫描combined.jar(包含工程中所有.class文件)匹配出我们自定义的maindexlist.txt,再替换掉build/multi-dex/maindexlist.txt,和build实例。这样分包的时候就会基于我们的规则生成主Dex。
101100

102101
###Congratulation
103102
恭喜,填坑终于结束,不过还有点不爽的是需要同时维护Gradle脚本和插件的配置。
104-
于是就将Gradle脚本整合进了插件,以后只要维护一个配置文件就行了。由于带有点业务特性,于是就单独开了个项目,读者可以根据自己需求自己选择。以下是整合插件的配置。
103+
于是乎就将Gradle脚本整合进了插件,这样只需维护一个配置文件就行了。读者可以根据自己需求自行选择分开配置还是整合配置。通过这种方式我们把主Dex的方法数维持在15000左右,从此再也不用担心方法数问题了!!!
105104

106105
##配置部分
107106
**第一步:将repo目录复制到项目根目录**
@@ -111,8 +110,8 @@ afterEvaluate {
111110
buildscript {
112111
repositories {
113112
maven {
114-
url uri('repo')
115-
}
113+
url uri('repo')
114+
}
116115
}
117116
118117
dependencies {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy