说明
apktool在window上使用,有的apk会有"brut.androlib.AndrolibException: brut.common.BrutException...(很长一串命令)",导致回编失败,同样的环境换到linux上就没得这个问题
原因
cmd命令行长度有限制,Windows XP或更高版本,最大长度8191个字符。如果超过8191就会有问题。一般apk回编是没得问题,如果apk中不压缩的资源太多就会造成回编失败的问题,不压缩资源目录在apktool.yml
中
!!brut.androlib.meta.MetaInfo
apkFileName: demo.apk
compressionType: false
doNotCompress://不压缩文件列表
- arsc
- png
- txt
- jar
- assets/UI_Bundles/UI_Bundles
- manifest
- unity3d
- assets/UI_Bundles/ui/materials.unity3d.manifest
- assets/UI_Bundles/ui/anim.unity3d.manifest
...
- assets/Lua_Bundles/lua/ui/equip/equipgroup.unity3d.manifest
- csv
- json
isFrameworkApk: false
packageInfo:
forcedPackageId: '127'
renameManifestPackage: null
sdkInfo:
minSdkVersion: '14'
targetSdkVersion: '26'
sharedLibrary: false
sparseResources: false
unknownFiles: {}
usesFramework:
ids:
- 1
tag: null
version: 2.4.1-SNAPSHOT
versionInfo:
versionCode: '919'
versionName: 2.7.0
apktool回编代码片段
路径:Apktool/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java
private void aapt1Package(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include,
List<String> cmd, boolean customAapt)
throws AndrolibException {
cmd.add("p");
...
if (apkOptions.doNotCompress != null) {//判断是否有不进行压缩的目录,如果有就加入cmd命令行中
for (String file : apkOptions.doNotCompress) {
cmd.add("-0");
cmd.add(file);
}
}
...
try {
OS.exec(cmd.toArray(new String[0]));
LOGGER.fine("command ran: ");
LOGGER.fine(cmd.toString());
} catch (BrutException ex) {
throw new AndrolibException(ex);
}
}
从代码中可以看出来在执行aapt资源编译时,把所有不压缩的资源加到了命令中,就会导致命令行过长
解决
-
修改windows命令行长度
我尝试了哈不行,如果有能修改命令行长度的方法望告知
-
修改Apktool命令执行长度
assets目录下的文件不会生成资源索引,所以当不压缩资源在assets目录下时我们可以不用加入到命令行中
修改为:
private void aapt1Package(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include,
List<String> cmd, boolean customAapt)
throws AndrolibException {
cmd.add("p");
...
StringBuilder sb = new StringBuilder();
if (apkOptions.doNotCompress != null) {//不压缩的文件列表
for (String file : apkOptions.doNotCompress) {
if(file.startsWith("assets")) {//assets目录下的文件不需要参与资源编译
sb.append(file).append("\n");
continue;
}
cmd.add("-0");
cmd.add(file);
}
}
...
try {
OS.exec(cmd.toArray(new String[0]));
LOGGER.fine("command ran: ");
LOGGER.fine(cmd.toString());
//将为未加入命令行的资源名称输出到apk同目录,排查问题时使用
File doNotBuildFile = new File(apkOptions.outApkParentPath, "doNotBuild.log");
doNotBuildFile.getParentFile().mkdirs();
FileUtils.writeStringToFile(doNotBuildFile, sb.toString(), "utf-8");
} catch (BrutException ex) {
throw new AndrolibException(ex);
}
}
同理使用aapt2的修改aapt2Package
方法,这样修改后命令行长度很难超过8191
网友评论