Android-Dex分包最全总结:含Facebook解决方案

}
Dex merged = new DexMerger(dexes.toArray(new Dex[dexes.size()]), CollisionPolicy.FAIL).merge();
return merged.getBytes();
}
}

这里可以看到变量 libraryDexBuffers ,是一个 List 集合,那么我们看一下这个集合在哪里添加数据的:

public class Main {
private static boolean processFileBytes(String name, long lastModified, byte[] bytes) {
boolean isClassesDex = name.equals(DexFormat.DEX_IN_JAR_NAME);
//blablabla…
} else if (isClassesDex) {
synchronized (libraryDexBuffers) {
libraryDexBuffers.add(bytes);
}
return true;
} else {
//blablabla…
}
//调用processFileBytes的地方
private static class FileBytesConsumer implements ClassPathOpener.Consumer {

@Override
public boolean processFileBytes(String name, long lastModified,
byte[] bytes) {
return Main.processFileBytes(name, lastModified, bytes);
}
//blablabla…
}
//调用FileBytesConsumer的地方
private static void processOne(String pathname, FileNameFilter filter) {
ClassPathOpener opener;

opener = new ClassPathOpener(pathname, true, filter, new FileBytesConsumer());

if (opener.process()) {
updateStatus(true);
}
}
//调用processOne的地方
private static boolean processAllFiles() {
//blablabla…
// forced in main dex
for (int i = 0; i < fileNames.length; i++) {
processOne(fileNames[i], mainPassFilter);
}
//blablabla…
}
//调用processAllFiles的地方
private static int runMonoDex() throws IOException {
//blablabla…
if (!processAllFiles()) {
return 1;
}
//blablabla…
}

}

跟了一圈又跟回来了,但是注意一个变量:fileNames[i],传进去这个变量,是个地址,最终在 processFileBytes 中处理后添加到 libraryDexBuffers 中,那跟一下这个变量:

public class Main {
private static boolean processAllFiles() {
//blablabla…
String[] fileNames = args.fileNames;
//blablabla…
}
public void parse(String[] args) {
//blablabla…
}else if(parser.isArg(INPUT_LIST_OPTION + “=”)) {
File inputListFile = new File(parser.getLastValue());
try{
inputList = new ArrayList();
readPathsFromFile(inputListFile.getAbsolutePath(), inputList);
} catch(IOException e) {
System.err.println("Unable to read input list file: " + inputListFile.getName());
throw new UsageException();
}
} else {
//blablabla…
fileNames = parser.getRemaining();
if(inputList != null && !inputList.isEmpty()) {
inputList.addAll(Arrays.asList(fileNames));
fileNames = inputList.toArray(new String[inputList.size()]);
}
}

public static void main(String[] argArray) throws IOException {
Arguments arguments = new Arguments();
arguments.parse(argArray);

int result = run(arguments);
if (result != 0) {
System.exit(result);
}
}
}

跟到这里发现是传进来的参数,那我们再看看 gradle 里面传的是什么参数吧,查看 Dex task :

public class Dex extends BaseTask {
@InputFiles
Collection libraries
}
我们把这个参数打印出来:

afterEvaluate {
tasks.matching {
it.name.startsWith(‘dex’)
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = []
}
println dx.libraries
}
}

打印出来发现是 build/intermediates/pre-dexed/ 目录里面的 jar 文件,再把 jar 文件解压发现里面就是 dex 文件了。所以 DexMerger 的工作就是合并这里的 dex 。

更改编译环境

buildscript {
//…
dependencies {
classpath ‘com.android.tools.build:gradle:2.1.0-alpha3’
}
}

将 gradle 设置为 2.1.0-alpha3 之后,在项目的 build.gradle 中即使没有设置 multiDexEnabled true 也能够编译通过,但是生成的 apk 包依旧是两个 dex ,我想的是可能为了设置 instantRun 。

解决 65536

Google MultiDex 解决方案:

在 gradle 中添加 MultiDex 的依赖:

dependencies { compile ‘com.android.support:MultiDex:1.0.0’ }

在 gradle 中配置 MultiDexEnable :

android {
buildToolsVersion “21.1.0”
defaultConfig {
// Enabling MultiDex support.
MultiDexEnabled true
}
}

在 AndroidManifest.xml 的 application 中声明:


如果有自己的 Application 了,让其继承于 MultiDexApplication 。

如果继承了其他的 Application ,那么可以重写 attachBaseContext(Context):

@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}

LinearAlloc

gradle:

afterEvaluate {
tasks.matching {
it.name.startsWith(‘dex’)
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = []
}
dx.additionalParameters += ‘–set-max-idx-number=48000’
}
}

–set-max-idx-number= 用于控制每一个 dex 的最大方法个数。

这个参数在查看 dx.jar 找到:

//blablabla…
} else if (parser.isArg(“–set-max-idx-number=”)) { // undocumented test

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值