How to change the proguard mapping file name in gradle for Android project
As of today (May 2020) former solution, which uses variant.mappingFile
is not working anymore in new Android Gradle plugin (Android Studio) 3.6 and higher.
Instead variant.mappingFile
returns null
and following is displayed in the logs:
WARNING: API 'variant.getMappingFile()' is obsolete and has been replaced with 'variant.getMappingFileProvider()'.
I am sharing my working solution, which uses new 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)
}
}
}
}
Note, that variant.getBuildType().isMinifyEnabled() is not used since we are using DexGuard.
The code above makes mapping file's name match apk's file name.
Just in case, if you need to change apk name - following could be used:
android {
defaultConfig {
//resulting apk will looks like: "archive base name" + -<flavour>-<buildType>.apk
archivesBaseName = "$applicationId-$versionName"
}
}
Append version number into proguard mapping folder
Following¹ will rename mapping.txt
to mapping-release-1.0.1.txt
in the same folder.
In the module build.gradle
file:
android {
// lots of gradle code
// The following portion renames the mapping.txt file.
applicationVariants.all { variant ->
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
variant.mappingFile.renameTo(file(
"${variant.mappingFile.parent}/mapping-${variant.name}-${variant.versionName}.txt"))
}
}
}
}
You may also use variant.versionCode
or other options in the file name.
Hope this helps.
Difficulties setting up Gradle to send ProGuard mapping files to Firebase
gradle.properties is owned and managed completely by you. You have to create it if it doesn't already exist. This means you should probably read the Gradle documentation on it to best understand how it provides properties to your builds, and which location is best for your properties.
You are not even obliged to use gradle.properties. You can also specify all the properties for the Crash Reporting plugin via the command line.
When you specify a path for the service account file, you should specify the full, unambiguous path to the file. In your example, it looks like you're assuming that it will look under the app directory in your project. If you want to do that, you still have to give the full path to the file.
Where does Android Studio save the ProGuard mapping file?
It should be located at build/outputs/proguard/release/mapping.txt
in your application module's directory.
In the latest version of ProGuard and Android Studio, the file is located at build/outputs/mapping/release/mapping.txt
.
How to get ProGuard mapping file of previous release build
The mapping file is overwritten after every build so you probably lost it for good.
The best approach I can think of would be versioning your code with some VCS (Git, for example) and moving the mapping file to a location that is not being gitignored.
To move the generated proguard mapping file to a different path check this answer. You can even rename it if you like.
How to use gradle and proguard printmapping to create out.map file with version code
So, this is how it done
first define a function to get the version name
def getVersionName() {
File stringsXmlFile = new File("src\\main\\res\\values\\strings.xml")
String contents = stringsXmlFile.getText()
String version = contents.find("<string name=\"version\">[^<]*</string>");
version = version.replace("<string name=\"version\">", "").replace("string>", "")
version = version.replace("<", "")
version = version.substring(0, version.length() - 1)
return version
}
second, define after task function
gradle.taskGraph.afterTask { Task task, TaskState state ->
if (task.name.equals("assembleRelease")) {
File proguard = new File("build\\outputs\\apk\\out.map")
proguard.renameTo("build\\outputs\\apk\\out-" + getVersionName() + ".map")
}
}
that's it.
Gradle, task to copy mapping file
This is the snippet I use. It does depend on having a productFlavor
defined but that is only to help name the file and allow the same snippet to be reused in multiple projects without modification but that dependency could be refactored out if you wanted a different filename format.
As it stands, the apk and the mapping file (if required) will be copied to the defined basePath in the format:
FilePath\appname\appname buildtype versionname (versioncode)
e.g
A:\Common\Apk\MyAppName\MyAppName release 1.0 (1).apk
and
A:\Common\Apk\MyAppName\MyAppName release 1.0 (1).mapping
Amend as you see fit.
android {
productFlavors {
MyAppName {
}
}
//region [ Copy APK and Proguard mapping file to archive location ]
def basePath = "A:\\Common\\Apk\\"
applicationVariants.all { variant ->
variant.outputs.each { output ->
// Ensure the output folder exists
def outputPathName = basePath + variant.productFlavors[0].name
def outputFolder = new File(outputPathName)
if (!outputFolder.exists()) {
outputFolder.mkdirs()
}
// set the base filename
def newName = variant.productFlavors[0].name + " " + variant.buildType.name + " " + defaultConfig.versionName + " (" + defaultConfig.versionCode + ")"
// The location that the mapping file will be copied to
def mappingPath = outputPathName + "\\" + newName + ".mapping"
// delete any existing mapping file
if (file(mappingPath).exists()) {
delete mappingPath
}
// Copy the mapping file if Proguard is turned on for this build
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
copy {
from variant.mappingFile
into output.outputFile.parent
rename { String fileName ->
newName + ".mapping"
}
}
}
}
// Set the filename and path that the apk will be created at
if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
def path = outputPathName + "\\" + newName + ".apk"
if (file(path).exists()) {
delete path
}
output.outputFile = new File(path)
}
}
}
//endregion
}
Related Topics
Button in Custom Android Toast
Lint Error "Do Not Treat Position as Fixed; Only Use Immediately..."
Delete File from Internal Storage
Okhttp Library - Networkonmainthreadexception on Simple Post
Android Audiotrack Playing .Wav File, Getting Only White Noise
Android Studio 3.0 Compile Issue (Cannot Choose Between Configurations)
Android Decoder->Decode Returned False for Bitmap Download
Auto Start Application After Boot Completed in Android
Android: Custom Separator (Or Even Item) in Listview Depening on Content of Item
How Can Android Source Code Not Have a Main Method and Still Run
Intent Putextra Arraylist<Namevaluepair>
Is Arm64-V8A Compatible with Armeabi-V7A
How to Detect Wifi Tethering State