使用d8编译工具构建JAR包时如何保留MANIFEST.MF文件?
问题原因
d8的核心定位是Java字节码转Dex字节码的编译工具,输出的Jar包仅会包含编译生成的classes.dex文件,不会自动继承原始Jar包中的MANIFEST.MF等元数据,也没有内置参数支持保留原始Manifest,因此需要额外添加合并步骤实现需求。
解决方案
调整构建流程,先让d8输出编译后的Dex到临时文件,再通过Jar打包任务将Manifest和Dex合并为最终产物,修改后的Gradle脚本如下:
def jarPath = buildDir.absolutePath + "/libs" def jarBaseName = "plugin" task buildJar(dependsOn: build, type: Jar) { doFirst { manifest { attributes 'Jar-VersionCode': jarVersionCode } } from zipTree(file('build/intermediates/aar_main_jar/release/classes.jar')) // [archiveBaseName]-[archiveAppendix]-[archiveVersion]-[archiveClassifier].[archiveExtension] archiveBaseName = jarBaseName archiveAppendix = null archiveVersion = "$jarVersionName-$jarVersionCode" archiveClassifier = "release" archiveExtension = "jar" destinationDirectory = file(jarPath) } // dx --dex --output=output.jar input.jar task buildDex1(dependsOn: buildJar, type: Exec) { workingDir jarPath executable "dx" args "--dex" args "--output=" + buildJar.archiveFileName.get() args buildJar.archiveFileName.get() } // ---------- 修改后的d8构建流程 ---------- // 第一步:d8编译生成仅含dex的临时Jar task buildDexTemp(dependsOn: buildJar, type: Exec) { workingDir jarPath executable "d8" args "--release" args "--output" args "temp_dex.jar" // 临时输出,不覆盖原Jar args buildJar.archiveFileName.get() } // 第二步:合并Manifest和Dex,生成最终Jar task buildDex2(dependsOn: buildDexTemp, type: Jar) { // 复用原Manifest配置 manifest { attributes 'Jar-VersionCode': jarVersionCode } // 导入d8编译生成的dex文件 from zipTree(file("${jarPath}/temp_dex.jar")) // 保持输出配置和原buildJar一致 archiveBaseName = jarBaseName archiveAppendix = null archiveVersion = "$jarVersionName-$jarVersionCode" archiveClassifier = "release" archiveExtension = "jar" destinationDirectory = file(jarPath) // 构建完成后清理临时文件 doLast { delete file("${jarPath}/temp_dex.jar") // 可选:删除buildJar生成的原始非dex Jar,避免混淆 delete buildJar.archiveFile.get() } }
如果原有构建链路依赖buildDex2,无需调整依赖关系,直接执行即可得到带Manifest的Dex Jar包。
内容的提问来源于stack exchange,提问作者DysaniazzZ
相关产品推荐
相关产品推荐

