Open hanklzl opened 3 years ago
同样的问题,在Android studio 4.2.0版本上出现。 打包apk、打包补丁patch、直接在真机上run都没有问题,但是Rebuild project的时候就会出现。 添加使用task.all{...}代码,也不起作用。 gradle版本:gradle-6.5-all gradle插件版本:gradle:4.1.3
顶一下,AGP 4.2.1, gradle 7.0.0同样的问题,如下
执行:gradle clean && gradle assembleRelease
正常
执行:gradle clean assembleRelease
报错
版本1.9.14.16
实测注释掉TinkerPatchPlugin中TinkerResourceIdTask.injectStableIdsFileOnDemand(mProject)
后正常
该问题可通过以下方式修复:
def createFile(path) {
File file = new File(path)
if (!file.exists()) {
file.createNewFile()
}
}
android.applicationVariants.all { variant ->
/**
* task type, you want to bak
*/
def taskName = variant.name
def path = "${buildDir}/intermediates/tinker_intermediates/public.txt"
tasks.all {
if ("process${taskName.capitalize()}Resources".equalsIgnoreCase(it.name)) {
it.doFirst {
createFile(path)
}
}
}
}
该问题可通过以下方式修复:
def createFile(path) { File file = new File(path) if (!file.exists()) { file.createNewFile() } } android.applicationVariants.all { variant -> /** * task type, you want to bak */ def taskName = variant.name def path = "${buildDir}/intermediates/tinker_intermediates/public.txt" tasks.all { if ("process${taskName.capitalize()}Resources".equalsIgnoreCase(it.name)) { it.doFirst { createFile(path) } } } }
亲测可用
android.applicationVariants.all { variant -> /**
task type, you want to bak */ def taskName = variant.name def path = "${buildDir}/intermediates/tinker_intermediates/public.txt"
tasks.all { if ("process${taskName.capitalize()}Resources".equalsIgnoreCase(it.name)) { it.doFirst { createFile(path) } } } }
亲测可用
异常类型:编译异常
手机型号:
手机系统版本:
tinker版本:如:1.9.14.15
gradle版本:如: AGP 3.6.3, gradle 6.1.1
是否使用热更新SDK: 否
系统:Mac/Linux
堆栈/日志:
这个问题应该是近期Tinker版本引入的,构建基线包(TinkerEnable = true)时当编译命令将clean和assemble同时使用时,例如./gradlew clean assembleDebug,就会出现,此时编译的过程为:
AGP创建ProcessResourcesTask,实例化并将aaptOptions设置进去,具体代码位置在LinkApplicationAndroidResourcesTask这个类中(以AGP 3.6.3为例),此时设置进ProcessResourcesTask的aaptOptions是包含 --stable-ids xxx/tinker_intermediates/public.txt 的![image](https://user-images.githubusercontent.com/4076240/115558726-9969f280-a2e5-11eb-8f29-b9a5d4272a48.png)
gradle配置完成开始执行task,会先执行clean清理build目录,整个tinker_intermediates会被删除,里面的public.txt也会被对应删除
执行到ProcessResourcesTask时,aapt2命令就会因为对应的public.txt不存在而报错。
这个问题本身不会影响patch构建,因为执行TinkerResourceIdTask时会调用ensureStableIdsArgsWasInjected方法再补充创建public.txt文件。
我试了下tinker-sample-android没有问题是因为app/build.gradle中这段代码:
遍历所有tasks可能会使Task提前创建,导致sample中构建基线包的执行顺序变为:
所以sample才没有问题,实际测试,如果注释掉上面的这段代码,是能够复现该问题的。
所以我的问题是,TinkerPatchPlugin中TinkerResourceIdTask.injectStableIdsFileOnDemand(mProject)这个操作是不是可以去掉了?因为在TinkerResourceIdTask里面也会保证aaptOptions的正确配置和public.txt的存在
Tinker是一个开源项目,希望大家遇到问题时要学会先思考,看看sample与Tinker的源码,更鼓励大家给我们提pr.