Open yanbober opened 2 years ago
修复问题 https://github.com/Tencent/tinker/issues/1648
问题本质原因分析如下:
static String readManifestApplicationName(def project, String manifestPath) { def isr = null try { isr = new InputStreamReader(new FileInputStream(manifestPath), "utf-8") def xml = new XmlParser().parse(isr) def ns = new Namespace("http://schemas.android.com/apk/res/android", "android") def application = xml.application[0] def applicationName = null if (application) { applicationName = application.attributes()[ns.name] application.attributes().each { k, v-> project.logger.error("FROM XmlParser: ${k.getClass()}---${k.namespaceURI}, ${k.localPart}") project.logger.error("FROM Namespace: ${ns.name.getClass()}---${ns.name.namespaceURI}, ${ns.name.localPart}") if (k.namespaceURI.equals(ns.name.namespaceURI) && k.localPart.equals(ns.name.localPart)) { project.logger.error("=============matched 1") } if (k.equals(ns.name)) { project.logger.error("=============matched 2") } } } return applicationName } finally { IOHelper.closeQuietly(isr) } }
如上代码在高版本 gradle 配合 agp 中输出:
FROM XmlParser: class groovy.xml.QName---http://schemas.android.com/apk/res/android, name FROM Namespace: class groovy.namespace.QName---http://schemas.android.com/apk/res/android, name =============matched 1
低版本中没问题,分析发现,高低版本 gradle 依赖的 groovy 版本不一样。
低版本: groovy.util.XmlParser 内部对应 groovy.xml.QName groovy.xml.Namespace 内部对应 groovy.xml.QName 所以从 application.attributes() 的 map 中通过 QName key 去获取是可以找到对应 hashkey 的 value。
高版本: groovy.util.XmlParser 内部对应 groovy.xml.QName groovy.xml.Namespace 内部对应 groovy.namespace.QName 所以从 application.attributes() 的 map 中通过 QName key 去获取是无法找到对应 hashkey 的 value,因为类名 QName 相同,但是 package name 已经不同了,导致 equals 方法无法相等,除非 XmlParser 也使用 groovy.xml 包下的,但是高版本 groovy 才有这个。
因此修复方案换成 XmlSlurper 即可兼容高低不同版本 groovy。
修复问题 https://github.com/Tencent/tinker/issues/1648
问题本质原因分析如下:
如上代码在高版本 gradle 配合 agp 中输出:
低版本中没问题,分析发现,高低版本 gradle 依赖的 groovy 版本不一样。
低版本: groovy.util.XmlParser 内部对应 groovy.xml.QName groovy.xml.Namespace 内部对应 groovy.xml.QName 所以从 application.attributes() 的 map 中通过 QName key 去获取是可以找到对应 hashkey 的 value。
高版本: groovy.util.XmlParser 内部对应 groovy.xml.QName groovy.xml.Namespace 内部对应 groovy.namespace.QName 所以从 application.attributes() 的 map 中通过 QName key 去获取是无法找到对应 hashkey 的 value,因为类名 QName 相同,但是 package name 已经不同了,导致 equals 方法无法相等,除非 XmlParser 也使用 groovy.xml 包下的,但是高版本 groovy 才有这个。
因此修复方案换成 XmlSlurper 即可兼容高低不同版本 groovy。