tinker
tinker copied to clipboard
Fix failed to write manifest in AGP 4.1.
tinker 在 process${variant.name.capitalize()}Manifest
任务的产物 build/intermediates/merged_manifests
目录中的 AndroidManifest.xml
文件中写入了 tinker_id
等信息,而 AGP 4.1 新增了在 process${variant.name.capitalize()}Manifest
任务之后执行的任务 process${variant.name.capitalize()}ManifestForPackage
,该任务的产物在 build/intermediates/packaged_manifests
目录中。
如果这 2 个任务命中了 gradle 缓存,执行状态都是 FROM-CACHE
,那么最终 APK 中 manifest 文件中的 tinker_id
等信息是以前编译写入的旧信息。因此,对于 AGP 4.1,向 manifest 写入信息的时机应该改为 process${variant.name.capitalize()}ManifestForPackage
执行后,且目标文件应该改为 build/intermediates/packaged_manifests
目录中的 AndroidManifest.xml
文件。
@tomystang
已解决! 感谢!
两种解决方案 :
- 有条件的可以自己clone 工程修改 gradle 升级到 7.x TinkerManifestTask 修改 writeManifestMeta 方法的XmlParse 升级到7.0 以后 ,groovy XmlParse api发生变化
- // 禁用 tinker tinker_id task 写入 ,自己实现
project.tasks.all { Task task ->
if (task.name == "processArm32ReleaseManifest") {
task.doLast {
def file = new File((task as ProcessMultiApkApplicationManifest).getMultiApkManifestOutputDirectory().get().asFile, "AndroidManifest.xml")
writeManifestMeta(file.absolutePath, "TINKER_ID", getShortCommitId())
}
} else if (task.name == "tinkerProcessArm32ReleaseManifest") {
task.enabled = false
}
}
def writeManifestMeta(String manifestPath, String name, String value) {
def ns = new Namespace("http://schemas.android.com/apk/res/android", "android")
def isr = null
def pw = null
try {
isr = new InputStreamReader(new FileInputStream(manifestPath), "utf-8")
def xml = new groovy.xml.XmlParser().parse(isr) as Node
def application = xml.application[0] as Node
if (application) {
def metaDataTags = application['meta-data']
// remove any old TINKER_ID elements
def tinkerId = metaDataTags.findAll {
it.attributes()[ns.name].equals(name)
}.each {
it.parent().remove(it)
}
// Add the new TINKER_ID element
application.appendNode('meta-data', [(ns.prefix + ':name'): name, (ns.prefix + ':value'): value])
// Write the manifest file
pw = new PrintWriter(manifestPath, "utf-8")
def printer = new groovy.xml.XmlNodePrinter(pw)
printer.preserveWhitespace = true
printer.print(xml)
}
} finally {
IOHelper.closeQuietly(pw)
IOHelper.closeQuietly(isr)
}
}
亲测,使用这篇的配置,打包就没有问题了:
Gradle插件版本(3.6.3):classpath 'com.android.tools.build:gradle:3.6.3'
Gradle版本(5.6.4):distributionUrl=https://services.gradle.org/distributions/gradle-5.6.4-all.zip
Bugly Gradle插件版本(1.2.3):classpath "com.tencent.bugly:tinker-support:1.2.3"
Tinker插件版本(1.9.14.16):implementation 'com.tencent.tinker:tinker-android-lib:1.9.14.16'