最近要编译一个使用私有接口的系统应用,记录一下流程。
1.首先要下载带有隐藏接口的android.jar包,可以到
https://drive.google.com/drive/folders/185jgOthBI_qXzeS14s795LMGSekSTw5_
下载,下载完之后替换sdk下面对应平台的jar包
2.编译碰到
Could not resolve all files for configuration ':mdm:androidApis'.
Failed to transform android.jar to match attributes {artifactType=android-mockable-jar, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime, returnDefaultValues=false}.
Execution failed for MockableJarTransform:
我主要参考
https://blog.csdn.net/qq_26413249/article/details/109819624帖子解决的,但是完全参照这个方法,还是回碰到问题
transform output android.jar must exist
帖子是createMockableJar引入空实现,这样不会输出android.jar包,我的方案是createMockableJar还是之前的实现,只是修改fixMethodBody方法。具体实现为:
private void fixMethodBody(MethodNode methodNode, ClassNode classNode) {
if ((methodNode.access & Opcodes.ACC_ABSTRACT) != 0) {
// Abstract methods don't have bodies to rewrite.
return;
}
if ((classNode.access & Opcodes.ACC_ENUM) != 0 && ENUM_METHODS.contains(methodNode.name)) {
// Don't break enum classes.
return;
}
Type returnType = Type.getReturnType(methodNode.desc);
InsnList instructions = methodNode.instructions;
if (instructions == null) {
// Create a body if the method didn't have it, e.g. if it was native.
instructions = new InsnList();
methodNode.instructions = instructions;
}
if (methodNode.name.equals(CONSTRUCTOR)) {
// Keep the call to parent constructor, delete the exception after that.
boolean deadCode = false;
for (AbstractInsnNode instruction : instructions.toArray()) {
if (!deadCode) {
if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) {
instructions.insert(instruction, new InsnNode(Opcodes.RETURN));
// Start removing all following instructions.
deadCode = true;
}
} else {
instructions.remove(instruction);
}
}
} else {
instructions.clear();
if (returnDefaultValues || methodNode.name.equals(CLASS_CONSTRUCTOR)) {
if (INTEGER_LIKE_TYPES.contains(returnType)) {
instructions.add(new InsnNode(Opcodes.ICONST_0));
} else if (returnType.equals(Type.LONG_TYPE)) {
instructions.add(new InsnNode(Opcodes.LCONST_0));
} else if (returnType.equals(Type.FLOAT_TYPE)) {
instructions.add(new InsnNode(Opcodes.FCONST_0));
} else if (returnType.equals(Type.DOUBLE_TYPE)) {
instructions.add(new InsnNode(Opcodes.DCONST_0));
} else if (!returnType.equals(Type.VOID_TYPE)) {
instructions.add(new InsnNode(Opcodes.ACONST_NULL));
}
instructions.add(new InsnNode(returnType.getOpcode(Opcodes.IRETURN)));
} /*else {
instructions.insert(throwExceptionsList(methodNode, classNode));
}*/
}
}
这样就完全跑通