如何在Android项目的gradle中更改proguard映射文件名

ole*_*flo 23 obfuscation android proguard gradle

我有基于gradle的android项目,我想在为我的构建生成后更改mapping.txt文件名.怎么做到呢?

UPD

如何在build.gradle中完成?由于我可以访问我的口味和其他僵硬,我想基于flavor/build变体版本创建映射文件名.

igo*_*pst 45

更简单的解决方案

applicationVariants.all { variant ->
        if (variant.getBuildType().isMinifyEnabled()) {
            variant.assemble.doLast {
                copy {
                    from variant.mappingFile
                    into "${rootDir}/proguardTools"
                    rename { String fileName ->
                        "mapping-${variant.name}.txt"
                    }
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果您只需要重命名现有的映射文件而不将其复制到新位置,请使用以下代码片段:`def mappingFile = variant.mappingFile mappingFile.renameTo(mappingFile.parent +"/ newName.txt")` (4认同)
  • 非常好,谢谢.您也可以使用`rename {String fileName - >"mapping - $ {variant.getFlavorName()}.txt"}`如果您有多种产品风格并且不想包含buildType. (2认同)

Kon*_*iak 7

在proguard-rules.pro文件中使用此命令:

-printmapping path/to/your/file/file_name.txt
Run Code Online (Sandbox Code Playgroud)

该文件将被写入部分{root}/path/to/your/filefile_name.txt名称.

如果您想为不同的口味设置不同的设置,可以为它们定义许多proguard规则

我发现了另外一个想法,但我不确定它是否正确.

您可以在flavor中定义路径:

productFlavors {
    test1 {
        applicationId "com.android.application.test"
        project.ext."${name}Path" = 'path/one/mapp.txt'
    }
    test2 {
        project.ext."${name}Path" = 'path/two/mapp.txt'
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来您可以在$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);
}
Run Code Online (Sandbox Code Playgroud)

并在脚本中${root}/utils/test.bash- 您可以修改proguard-rules.pro.

但我认为存在更好的解决方案.


Ale*_*lex 7

截至今天(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)
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

请注意,由于我们使用的是 DexGuard,因此未使用变体.getBuildType().isMinifyEnabled()

上面的代码使映射文件的名称与 apk 的文件名匹配。

以防万一,如果您需要更改 apk 名称 - 可以使用以下内容:

android {
    defaultConfig {
        //resulting apk will looks like: "archive base name" + -<flavour>-<buildType>.apk
        archivesBaseName = "$applicationId-$versionName"
    }
}

Run Code Online (Sandbox Code Playgroud)


ole*_*flo 5

非常感谢 Sergii Pechenizkyi,他帮助我找到了这个好的解决方案。

为了实现每个风味的 proguard 映射文件的复制,我们可以为每个风味创建“根”任务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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

之后我们应该在组装我们的项目后运行这个任务。我使用 jenkins,我的任务选项看起来像

gradle clean assembleProjectName copyProguardMapping
Run Code Online (Sandbox Code Playgroud)

它就像一个魅力。