描述:
和热修复同时使用的问题,methodId差异导致dexdiff差异多大且main dex上每次都有diff
解决方案: 通过配置baseMethodMap给matrix,将基准包的methodMapping信息提供给在构建差分包的前期构建new apk时使用,是的new apk的方法映射和old apk一致
debug环境下需要自动将methodid映射为具体的方法签名,增强堆栈可读性
解决方案: 在debug环境下将methodMapping文件在packageDebug task执行前放入assets目录进而打包进apk,展示前将assets信息读取并用来解析methodId
统计堆栈信息有时除了Handler.dispatchMessage(Message message)占据大量时间(700ms以上)但其他methodItem占用时间都很少(700多项方法调用,每项占据的时间都不大,但总时间较长),这种场景可以理解为在一次dispatchMessage中进行了过多任务的处理,每个任务都耗时不明显大,也是需要处理的。但还是要看清时间占用是在app中的方法还是系统方法里
比如dispatchMessage->分发onCreate时间处理逻辑方法任务数量过多
matrix-gradle-plugin中android plugin版本过低2.1.0–>3.2.1
普通java仓库先在构建过程确定依赖仓库的最新版本,但gradle plugin的构建过程在未确定依赖仓库的最新版本之前,只能使用自身配置的版本进行构建
2.1.0的android plugin版本再构建初期限制了构建者的android plugin版本也是2.1.0,因此需要升级
matrix-gradle-plugin中android plugin版本过低3.2.1–>3.6.1
compile 'com.android.tools.build:gradle:3.2.1'
此时如果exclude,会导致在新的gradle插件版本如3.6.1上,matrix plugin完全失效但没有报错信息
implementation(Libs.lib_matrxi_gradle_plugin) {
exclude group: 'com.android.tools.build'
}
原因1:
从gradle3.2.1–>3.6.1期间project.getTasks()发生了变化,原本
transformClassesWithDexBuilderFordebug和transformClassesWithDexFordebug两个任务不存在,
实际生效log:
[INFO][MatrixTraceTransform]successfully inject task:transformClassesWithDexBuilderForDebug [INFO][MatrixTraceTransform]successfully inject task:transformClassesWithDexBuilderForRelease
导致matrix插件反射修改的逻辑没有机会进入"successfully inject task":
try {
String[] hardTask = getTransformTaskName(extension.getCustomDexTransformName(), variant.getName());
for (Task task : project.getTasks()) {
for (String str : hardTask) {
if (task.getName().equalsIgnoreCase(str) && task instanceof TransformTask) {
TransformTask transformTask = (TransformTask) task;
Log.i(TAG, "successfully inject task:" + transformTask.getName());
Field field = TransformTask.class.getDeclaredField("transform");
field.setAccessible(true);
field.set(task, new MatrixTraceTransform(config, transformTask.getTransform()));
break;
}
}
}
原因2:
matrix插件使用反射修改output,并不是标准的方式利用outputProvider进行,这从3.2.1提升到3.6.1之后已经不行,生成不了dex文件
//反射修改了输出路径
replaceFile(directoryInput, dirOutput);
replaceChangedFile(directoryInput, outChangedFiles);
原本的反射思路:
Collection<TransformInput> inputs = transformInvocation.getInputs();
for (TransformInput input : inputs) {
for (DirectoryInput directoryInput : input.getDirectoryInputs()) {
ImmutableDirectoryInput
@NonNull
private final Map<File, Status> changedFiles;
解决方案:
通过outputProvider提供的路径替代matrix固定的traceClass输出路径并删除原本的反射替换
final File dirOutput = outputProvider.getContentLocation(directoryInput.getName(), directoryInput.getContentTypes(), directoryInput.getScopes(), Format.DIRECTORY);
outputProvider.getContentLocation(inputJar.getName(), inputJar.getContentTypes()
, inputJar.getScopes(), Format.JAR)
从3.2.1->3.6.1之后methodMap没有正确copy到指定目录:apk中的assets
private class TraceClassAdapter extends ClassVisitor {
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
this.className = name;
if ((access & Opcodes.ACC_ABSTRACT) > 0 || (access & Opcodes.ACC_INTERFACE) > 0) {
this.isABSClass = true;
}
collectedClassExtendMap.put(className, superName);//这里gradle debug发现META-INF/versions/9/module-info.class时superName为null,分析得知需要修改isNeedTraceFile判断条件,UN_TRACE_CLASS新增"META-INF"
}