diff --git a/projects/sdk/core/gradle-plugin/src/main/kotlin/com/tencent/shadow/core/gradle/ShadowPlugin.kt b/projects/sdk/core/gradle-plugin/src/main/kotlin/com/tencent/shadow/core/gradle/ShadowPlugin.kt index 93df1a3b6..ff64fe2d5 100644 --- a/projects/sdk/core/gradle-plugin/src/main/kotlin/com/tencent/shadow/core/gradle/ShadowPlugin.kt +++ b/projects/sdk/core/gradle-plugin/src/main/kotlin/com/tencent/shadow/core/gradle/ShadowPlugin.kt @@ -241,26 +241,12 @@ class ShadowPlugin : Plugin { it.outputs.file(decodeXml).withPropertyName("decodeXml") it.doLast { - val jarPath = File(project.locateApkanalyzerResultPath().readText()) - val tempCL = URLClassLoader(arrayOf(jarPath.toURL()), contextClassLoader) - val binaryXmlParserClass = - tempCL.loadClass("com.android.tools.apk.analyzer.BinaryXmlParser") - val decodeXmlMethod = binaryXmlParserClass.getDeclaredMethod( - "decodeXml", - String::class.java, - ByteArray::class.java - ) - val zipFile = ZipFile(processedResFile) val binaryXml = zipFile.getInputStream( zipFile.getEntry("AndroidManifest.xml") ).readBytes() - val outputXmlBytes = decodeXmlMethod.invoke( - null, - "AndroidManifest.xml", - binaryXml - ) as ByteArray + val outputXmlBytes = decodeXml(project, binaryXml) decodeXml.parentFile.mkdirs() decodeXml.writeBytes(outputXmlBytes) } @@ -293,6 +279,50 @@ class ShadowPlugin : Plugin { (javacTask as JavaCompile).source(project.fileTree(relativePath)) } + /** + * 反射apkanalyzer中的BinaryXmlParser类的decodeXml方法 + */ + @Suppress("PrivateApi") + private fun decodeXml(project: Project, binaryXml: ByteArray): ByteArray { + val jarPath = File(project.locateApkanalyzerResultPath().readText()) + val tempCL = URLClassLoader(arrayOf(jarPath.toURL()), contextClassLoader) + val binaryXmlParserClass = + tempCL.loadClass("com.android.tools.apk.analyzer.BinaryXmlParser") + return try { + decodeXmlMethodV1(binaryXmlParserClass, binaryXml) + } catch (ignored: Exception) { + decodeXmlMethodV2(binaryXmlParserClass, binaryXml) + } + } + + private fun decodeXmlMethodV1(binaryXmlParserClass: Class<*>, binaryXml: ByteArray): ByteArray { + val decodeXmlMethod = binaryXmlParserClass.getDeclaredMethod( + "decodeXml", + String::class.java, + ByteArray::class.java + ) + return decodeXmlMethod.invoke( + null, + "AndroidManifest.xml", + binaryXml + ) as ByteArray + } + + /** + * 新版本代码中删掉了一个String参数,这个参数原来只用于log输出了 + * https://cs.android.com/android-studio/platform/tools/base/+/6a81855c2fa102ae4532ad9a645e40177770a26a:apkparser/analyzer/src/main/java/com/android/tools/apk/analyzer/BinaryXmlParser.java;dlc=598c38100e4fb2b001385faea994fcb54cc515b1 + */ + private fun decodeXmlMethodV2(binaryXmlParserClass: Class<*>, binaryXml: ByteArray): ByteArray { + val decodeXmlMethod = binaryXmlParserClass.getDeclaredMethod( + "decodeXml", + ByteArray::class.java + ) + return decodeXmlMethod.invoke( + null, + binaryXml + ) as ByteArray + } + /** * 检查插件是否修改了资源ID分区 *