我有基于gradle的android项目,我想在为我的构建生成后更改mapping.txt文件名。怎么办呢?
UPD
如何在build.gradle中完成?由于我可以访问我的口味和其他僵硬,我想根据flavor / build变体版本创建映射文件名。
答案 0 :(得分:43)
更简单的解决方案。
applicationVariants.all { variant ->
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
copy {
from variant.mappingFile
into "${rootDir}/proguardTools"
rename { String fileName ->
"mapping-${variant.name}.txt"
}
}
}
}
}
答案 1 :(得分:7)
在proguard-rules.pro文件中使用此命令:
-printmapping path/to/your/file/file_name.txt
该文件将使用{root}/path/to/your/file
名称部分file_name.txt
编写。
如果您想为不同的口味设置不同的设置,可以为它们定义许多proguard规则
我发现了另一个想法,但我不确定这是正确的方法。
您可以在风格中定义路径:
productFlavors {
test1 {
applicationId "com.android.application.test"
project.ext."${name}Path" = 'path/one/mapp.txt'
}
test2 {
project.ext."${name}Path" = 'path/two/mapp.txt'
}
}
接下来您可以在$asseble{variant.name.capitalize()}
任务之前定义新任务,如下所示:
android.applicationVariants.all { variant ->
def envFlavor = variant.productFlavors.get(0).name
def modifyProguardPath = tasks.create(name: "modifyProguardFor${variant.name.capitalize()}", type: Exec) {
def pathToMap = project."${envFlavor}Test1"
doFirst {
println "==== Edit start: $pathToMap ===="
}
doLast {
println "==== Edit end: $pathToMap ===="
}
executable "${rootDir}/utils/test.bash"
args pathToMap
}
project.tasks["assemble${variant.name.capitalize()}"].dependsOn(modifyProguardPath);
}
并在脚本${root}/utils/test.bash
中 - 您可以修改proguard-rules.pro
。
但我认为存在更好的解决方案。
答案 2 :(得分:4)
由于上次更新variant.mappingFile不再可用。 (我使用ProGuard 4.7版,AndroidStudio 2.0)
这是我的build.gradle文件的一部分:
import java.util.regex.Matcher
import java.util.regex.Pattern
def getCurrentFlavor() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern;
if( tskReqStr.contains( "assemble" ) )
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
Matcher matcher = pattern.matcher( tskReqStr )
if( matcher.find() )
return matcher.group(1).toLowerCase()
else
{
println "NO MATCH FOUND"
return "";
}
}
buildTypes {
release {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
minifyEnabled true
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, "${variant.name}_v${variant.versionName}.apk")
}
def mappingFile = "${rootDir}\\app\\build\\outputs\\mapping\\${getCurrentFlavor()}\\release\\mapping.txt"
println("mappingFile: ${mappingFile}")
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
copy {
from "${mappingFile}"
into "${rootDir}"
rename { String fileName ->
"mapping-${variant.name}.txt"
}
}
}
}
}
}
debug {
minifyEnabled false
useProguard false
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, "${variant.name}_v${variant.versionName}.apk")
}
}
}
}
答案 3 :(得分:4)
这是igorpst's answer的变体,但重命名mapping.txt以匹配apk的名称,包括应用版本名称。我将此与代码相结合,将APK命名为this answer中所述的版本号。我不得不窥探gradle源代码以找到$variant.baseName
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.company.app"
minSdkVersion 13
targetSdkVersion 21
versionCode 14 // increment with every release
versionName '1.4.8' // change with every release
archivesBaseName = "MyCompany-MyAppName-$versionName"
}
applicationVariants.all { variant ->
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
(new File(variant.mappingFile.parent, "$archivesBaseName-$variant.baseName-mapping.txt")).delete();
variant.mappingFile.renameTo(variant.mappingFile.parent +
"/$archivesBaseName-$variant.baseName-mapping.txt")
}
}
}
}
答案 4 :(得分:4)
截至今天(2020年5月)使用variant.mappingFile
的旧解决方案在新的Android Gradle插件(Android Studio) 3.6 及更高版本中不再起作用
相反,variant.mappingFile
返回null
,并在日志中显示以下内容:
警告:API'variant.getMappingFile()'已过时,并已替换为'variant.getMappingFileProvider()'。
我正在分享使用新api的工作解决方案:
applicationVariants.all { variant ->
variant.assembleProvider.get().doLast {
def mappingFiles = variant.getMappingFileProvider().get().files
for (file in mappingFiles) {
if (file != null && file.exists()) {
def nameMatchingApkFile = "$archivesBaseName-$variant.baseName-$file.name"
def newMappingFile = new File(file.parent, nameMatchingApkFile)
newMappingFile.delete() //clean-up if exists already
file.renameTo(newMappingFile)
}
}
}
}
请注意,由于我们使用的是DexGuard,因此未使用 variant.getBuildType()。isMinifyEnabled()。
上面的代码使映射文件的名称与apk的文件名匹配。
以防万一,如果您需要更改apk名称-可以使用以下内容:
android {
defaultConfig {
//resulting apk will looks like: "archive base name" + -<flavour>-<buildType>.apk
archivesBaseName = "$applicationId-$versionName"
}
}
答案 5 :(得分:3)
帮助我找到这个好解决方案的Sergii Pechenizkyi非常感谢。
为每种口味实现proguard映射文件的复制,我们可以创建&#34; root&#34;任务copyProguardMappingTask
和每种风味的动态任务数
def copyProguardMappingTask = project.tasks.create("copyProguardMapping")
applicationVariants.all { variant ->
variant.outputs.each { output ->
...
if (variant.getBuildType().isMinifyEnabled()) {
def copyProguardMappingVariantTask = project.tasks.create("copyProguardMapping${variant.name.capitalize()}", Copy)
def fromPath = variant.mappingFile;
def intoPath = output.outputFile.parent;
copyProguardMappingVariantTask.from(fromPath)
copyProguardMappingVariantTask.into(intoPath)
copyProguardMappingVariantTask.rename('mapping.txt', "mapping-${variant.name}.txt")
copyProguardMappingVariantTask.mustRunAfter variant.assemble
copyProguardMappingTask.dependsOn copyProguardMappingVariantTask
}
}
}
之后我们应该在组装项目后运行此任务。我使用jenkins,我的任务选项看起来像
gradle clean assembleProjectName copyProguardMapping
它就像一个魅力。
答案 6 :(得分:3)
variant.assemble
现在已弃用,建议的解决方案包含以前的修改:
archivesBaseName = "MyCompany-MyAppName-$versionName"
...
applicationVariants.all { variant ->
variant.assembleProvider.get().doLast {
if (variant.mappingFile != null && variant.mappingFile.exists()) {
def mappingFilename = "$archivesBaseName-$variant.baseName-mapping.txt"
(new File(variant.mappingFile.parent, mappingFilename)).delete()
variant.mappingFile.renameTo(variant.mappingFile.parent +
"/" + mappingFilename)
}
}
}
如果使用应用捆绑包(aab)而不是apk,请将其添加到android部分的 之后:
afterEvaluate {
bundleRelease.doLast {
android.applicationVariants.all { variant ->
if (variant.buildType.name == 'release') {
tasks.create(name: "renameMappingFile") {
if (variant.mappingFile != null && variant.mappingFile.exists()) {
variant.mappingFile.renameTo(variant.mappingFile.parent + "/$variant.baseName-$versionName-${new Date().format('yyyy-MM-dd_HHmm')}-mapping.txt")
}
}
}
}
}
}
在上一个示例中,也将bundleRelease
换为assembleRelease
换成apk。
更新:但是,如果您尝试直接在手机上构建常规调试,则最后一种方法不起作用。错误:
无法获得类型为org.gradle.api.Project的项目':app'的未知属性'bundleRelease'。
答案 7 :(得分:2)
所有这些答案都使用了复制来重命名文件。 我并不想移动文件,我只是想改变它的名字,记住构建类型和风格。
我基于这里其他海报的代码并稍微改了一下。 由于Minify可能是假的,但仍然使用proguard,我只是检查文件是否存在。
以下代码完成了这一点。
android {
applicationVariants.all { variant ->
variant.assemble.doLast {
def mappingFolderUrl = "${project.buildDir.path}/outputs/mapping/"
if (variant.buildType.name) {
mappingFolderUrl += variant.buildType.name + "/"
}
if (variant.flavorName) {
mappingFolderUrl += variant.flavorName + "/"
}
def mappingFileUrl = mappingFolderUrl + "mapping.txt"
logger.lifecycle("mappingFile path: ${mappingFileUrl}")
File mappingFile = file(mappingFileUrl)
if (mappingFile.exists()) {
def newFileName = mappingFolderUrl + "mapping-${variant.name}.txt"
mappingFile.renameTo(newFileName)
}
}
}
}
注意强>
您也可以使用此代码移动文件。
<。> .renameTo()方法需要一个完整的路径,如果你改变路径,我认为你有效地将文件移动到另一个地方。答案 8 :(得分:2)
对我有用的完整解决方案
applicationVariants.all { variant ->
def variantType = variant.buildType.name
if (variantType == "release") {
variant.assemble.doLast {
def mappingFile = variant.mappingFile
mappingFile.renameTo(mappingFile.parent + "/mapping-${variant.name}.txt")
}
}
}
答案 9 :(得分:1)
Android Studio Gradle插件版本3。3。0(2019年1月)的新功能
这克服了以前的问题,其中Android 3.0 / Android Gradle Plugin 3.0已弃用BuildType.isMinifyEnabled()
且gradle插件已弃用 variant.getAssemble()。
applicationVariants.all { variant ->
variant.assembleProvider.get().doLast {
if (variant.mappingFile != null && variant.mappingFile.exists()) {
def mappingFilename = "$archivesBaseName-$variant.baseName-mapping.txt"
(new File(variant.mappingFile.parent, mappingFilename)).delete()
variant.mappingFile.renameTo(variant.mappingFile.parent +
"/" + mappingFilename)
}
}
}
答案 10 :(得分:0)
上面的Pinhassi解决方案效果很好,它符合最新的Gradle变化。虽然我必须改变一些事情:
以下是完成的代码:
import java.util.regex.Matcher
import java.util.regex.Pattern
buildTypes {
release {
debuggable false
minifyEnabled true
proguardFiles 'proguard.cfg'
// Rename the apk file and copy the ProGuard mapping file to the root of the project
applicationVariants.all { variant ->
if (variant.getBuildType().name.equals("release")) {
def formattedDate = new Date().format('yyyyMMddHHmmss')
def projectName = ""
variant.outputs.each { output ->
def fullName = output.outputFile.name
projectName = fullName.substring(0, fullName.indexOf('-'))
// ${variant.name} has the value of "paidRelease"
output.outputFile = new File((String) output.outputFile.parent, (String) output.outputFile.name.replace(".apk", "-v${variant.versionName}-${formattedDate}.apk"))
}
def mappingFile = "${rootDir}/${projectName}/build/outputs/mapping/${getCurrentFlavor()}/release/mapping.txt"
println("mappingFile: ${mappingFile}")
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
copy {
from "${mappingFile}"
into "${rootDir}"
rename { String fileName ->
"mapping-${variant.name}.txt"
}
}
}
}
}
}
}
debug {
debuggable true
}
}
def getCurrentFlavor() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern;
if( tskReqStr.contains( "assemble" ) )
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
Matcher matcher = pattern.matcher( tskReqStr )
if( matcher.find() )
return matcher.group(1).toLowerCase()
else {
println "NO MATCH FOUND"
return "";
}
}
答案 11 :(得分:0)
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast{
copy {
from variant.mappingFile
into "${rootDir}/mapping"
rename { String fileName ->
"mapping-${variant.name}-${new Date().format('yyyy_MM_dd')}.txt"
}
}
}
}
}
}