how to verify crashlytics upload proguard mapping file
To make your app as small as possible, yous should enable shrinking in your release build to remove unused code and resources. When enabling shrinking, you too benefit from obfuscation, which shortens the names of your app'south classes and members, and optimization, which applies more than aggressive strategies to further reduce the size of your app. This page describes how R8 performs these compile-fourth dimension tasks for your project and how you can customize them.
When you build your project using Android Gradle plugin iii.4.0 or college, the plugin no longer uses ProGuard to perform compile-fourth dimension lawmaking optimization. Instead, the plugin works with the R8 compiler to handle the following compile-time tasks:
- Lawmaking shrinking (or tree-shaking): detects and safely removes unused classes, fields, methods, and attributes from your app and its library dependencies (making information technology a valuable tool for working around the 64k reference limit). For example, if you lot apply merely a few APIs of a library dependency, shrinking can identify library code that your app is non using and remove only that lawmaking from your app. To learn more, go to the section about how to compress your code.
- Resource shrinking: removes unused resources from your packaged app, including unused resources in your app's library dependencies. It works in conjunction with code shrinking such that once unused code has been removed, whatever resources no longer referenced tin be safely removed as well. To larn more, get to the department near how to shrink your resource.
- Obfuscation: shortens the name of classes and members, which results in reduced DEX file sizes. To learn more, go to the department about how to obfuscate your code.
- Optimization: inspects and rewrites your code to further reduce the size of your app's DEX files. For example, if R8 detects that the
else {}
branch for a given if/else statement is never taken, R8 removes the code for theelse {}
branch. To learn more, become to the section almost code optimization.
When building the release version of your app, past default, R8 automatically performs the compile-time tasks described higher up for you lot. Even so, you tin can disable certain tasks or customize R8's behavior through ProGuard rules files. In fact, R8 works with all of your existing ProGuard rules files, and then updating the Android Gradle plugin to employ R8 should not require yous to change your existing rules.
Enable shrinking, obfuscation, and optimization
When y'all use Android Studio 3.4 or Android Gradle plugin 3.four.0 and higher, R8 is the default compiler that converts your projection'due south Java bytecode into the DEX format that runs on the Android platform. Withal, when you lot create a new project using Android Studio, shrinking, obfuscation, and code optimization is not enabled by default. That'southward because these compile-time optimizations increase the build time of your project and might introduce bugs if you do not sufficiently customize which code to keep.
Then, it'southward best to enable these compile-time tasks when building the last version of your app that you test prior to publishing. To enable shrinking, obfuscation, and optimization, include the following in your project-level build.gradle
file.
Groovy
android { buildTypes { release { // Enables code shrinking, obfuscation, and optimization for simply // your project's release build type. minifyEnabled true // Enables resource shrinking, which is performed by the // Android Gradle plugin. shrinkResources true // Includes the default ProGuard rules files that are packaged with // the Android Gradle plugin. To acquire more, get to the section virtually // R8 configuration files. proguardFiles getDefaultProguardFile( 'proguard-android-optimize.txt'), 'proguard-rules.pro' } } ... }
Kotlin
android { buildTypes { getByName("release") { // Enables code shrinking, obfuscation, and optimization for only // your project'south release build type. isMinifyEnabled = true // Enables resources shrinking, which is performed by the // Android Gradle plugin. isShrinkResources = truthful // Includes the default ProGuard rules files that are packaged with // the Android Gradle plugin. To learn more than, go to the department about // R8 configuration files. proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt")), "proguard-rules.pro" ) } } ... }
R8 configuration files
R8 uses ProGuard rules files to alter its default behavior and ameliorate understand your app's structure, such equally the classes that serve as entry points into your app's code. Although y'all can change some of these rules files, some rules may be generated automatically past compile-time tools, such equally AAPT2, or inherited from your app's library dependencies. The table below describes the sources of ProGuard rules files that R8 uses.
Source | Location | Clarification |
Android Studio | <module-dir>/proguard-rules.pro | When yous create a new module using Android Studio, the IDE creates a proguard-rules.pro file in the root directory of that module. Past default, this file does not apply any rules. So, include your own ProGuard rules hither, such equally your custom keep rules. |
Android Gradle plugin | Generated past the Android Gradle plugin at compile fourth dimension. | The Android Gradle plugin generates proguard-android-optimize.txt , which includes rules that are useful to most Android projects and enables @Keep* annotations. By default, when creating a new module using Android Studio, the module-level Note: The Android Gradle plugin includes boosted predefined ProGuard rules files, just it is recommended that yous use |
Library dependencies | AAR libraries: <library-dir>/proguard.txt JAR libraries: | If an AAR library is published with its own ProGuard rules file, and you include that AAR as a compile-time dependency, R8 automatically applies its rules when compiling your project. Using rules files that are packaged with AAR libraries is useful if certain go on rules are required for the library to function properly—that is, the library developer has performed the troubleshooting steps for you. However, you should be aware that, considering ProGuard rules are additive, certain rules that an AAR library dependency includes cannot be removed and might bear on the compilation of other parts of your app. For example, if a library includes a rule to disable code optimizations, that rule disables optimizations for your entire projection. |
Android Asset Packet Tool ii (AAPT2) | Afterwards building your project with minifyEnabled true : <module-dir>/build/intermediates/proguard-rules/debug/aapt_rules.txt | AAPT2 generates keep rules based on references to classes in your app's manifest, layouts, and other app resources. For instance, AAPT2 includes a keep rule for each Activeness that y'all annals in your app's manifest as an entry point. |
Custom configuration files | By default, when you create a new module using Android Studio, the IDE creates <module-dir>/proguard-rules.pro for yous to add your own rules. | You can include boosted configurations, and R8 applies them at compile-time. |
When you lot set the minifyEnabled
property to true
, R8 combines rules from all the bachelor sources listed above. This is important to call back when yous troubleshoot with R8, because other compile-time dependencies, such as library dependencies, may introduce changes to the R8 behavior that you do non know about.
To output a total report of all the rules that R8 applies when edifice your project, include the following in your module's proguard-rules.pro
file:
// You can specify whatever path and filename. -printconfiguration ~/tmp/full-r8-config.txt
Include boosted configurations
When you lot create a new projection or module using Android Studio, the IDE creates a <module-dir>/proguard-rules.pro
file for you lot to include your ain rules. You can also include additional rules from other files past adding them to the proguardFiles
property in your module'due south build.gradle
file.
For example, you tin add rules that are specific to each build variant past adding another proguardFiles
belongings in the respective productFlavor
block. The post-obit Gradle file adds flavor2-rules.pro
to the flavor2
production flavor. Now, flavor2
uses all 3 ProGuard rules because those from the release
block are also practical.
Groovy
android { ... buildTypes { release { minifyEnabled truthful proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), // Listing additional ProGuard rules for the given build type here. By default, // Android Studio creates and includes an empty rules file for you (located // at the root directory of each module). 'proguard-rules.pro' } } flavorDimensions "version" productFlavors { flavor1 { ... } flavor2 { proguardFile 'flavor2-rules.pro' } } }
Kotlin
android { ... buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), // Listing boosted ProGuard rules for the given build type here. By default, // Android Studio creates and includes an empty rules file for you (located // at the root directory of each module). "proguard-rules.pro" ) } } flavorDimensions.add together("version") productFlavors { create("flavor1") { ... } create("flavor2") { proguardFile("flavor2-rules.pro") } } }
Compress your code
Code shrinking with R8 is enabled by default when y'all fix the minifyEnabled
belongings to truthful
.
Code shrinking (also known as tree shaking), is the process of removing code that R8 determines is not required at runtime. This process can greatly reduce your app'southward size if, for example, your app includes many library dependencies but utilizes merely a small part of their functionality.
To shrink your app's code, R8 first determines all entry points into your app's lawmaking based on the combined set up of configuration files. These entry points include all classes that the Android platform may use to open your app's Activities or services. Starting from each entry betoken, R8 inspects your app's code to build a graph of all methods, member variables, and other classes that your app might admission at runtime. Code that is not continued to that graph is considered unreachable and may be removed from the app.
Figure one shows an app with a runtime library dependency. While inspecting the app's lawmaking, R8 determines that methods foo()
, faz()
, and bar()
are reachable from the MainActivity.class
entry indicate. However, class OkayApi.course
or its method baz()
is never used past your app at runtime, and R8 removes that code when shrinking your app.
R8 determines entry points through -continue
rules in the project'southward R8 configuration files. That is, proceed rules specify classes that R8 should not discard when shrinking your app, and R8 considers those classes as possible entry points into your app. The Android Gradle plugin and AAPT2 automatically generate keep rules that are required by virtually app projects for you, such as your app's activities, views, and services. However, if you demand to customize this default behavior with additional go along rules, read the section near how to customize which code to keep.
If instead you are interested only in reducing the size of your app'due south resources, skip to the department about how to compress your resource.
Customize which lawmaking to keep
For about situations, the default ProGuard rules file (proguard-android- optimize.txt
) is sufficient for R8 to remove just the unused code. However, some situations are difficult for R8 to analyze correctly and it might remove lawmaking your app really needs. Some examples of when it might incorrectly remove code include:
- When your app calls a method from the Java Native Interface (JNI)
- When your app looks up code at runtime (such every bit with reflection)
Testing your app should reveal any errors acquired by inappropriately removed lawmaking, simply you can besides inspect what lawmaking was removed by generating a written report of removed code.
To set errors and strength R8 to keep certain code, add a -go along
line in the ProGuard rules file. For example:
-keep public class MyClass
Alternatively, you can add the @Go on
annotation to the lawmaking you want to keep. Calculation @Go on
on a class keeps the entire course every bit-is. Adding information technology on a method or field volition keep the method/field (and its name) as well as the class name intact. Note that this annotation is bachelor only when using the AndroidX Annotations Library and when you include the ProGuard rules file that is packaged with the Android Gradle plugin, as described in the section about how to enable shrinking.
There are many considerations you should make when using the -go along
pick; for more information nearly customizing your rules file, read the ProGuard Manual. The Troubleshooting section outlines other common problems you might meet when your lawmaking gets stripped away.
Strip native libraries
By default, native code libraries are stripped in release builds of your app. This stripping consists of removing the symbol table and debugging information contained in whatever native libraries used by your app. Stripping native code libraries results in significant size savings; yet, it's impossible to diagnose crashes on the Google Play Panel due to the missing data (such as class and function names).
Native crash support
The Google Play Console reports native crashes under Android vitals. With a few steps, you tin can generate and upload a native debug symbols file for your app. This file enables symbolicated native crash stack traces (that include class and part names) in Android vitals to help you debug your app in product. These steps vary depending on the version of the Android Gradle plugin used in your project and the build output of your project.
Android Gradle plugin version iv.1 or subsequently
If your projection builds an Android App Package, you can automatically include the native debug symbols file in it. To include this file in release builds, add the following to your app's build.gradle
file:
android.buildTypes.release.ndk.debugSymbolLevel = { SYMBOL_TABLE | FULL }
Select the debug symbol level from the following:
- Employ
SYMBOL_TABLE
to become function names in the Play Console's symbolicated stack traces. This level supports tombstones. - Use
FULL
to get role names, files, and line numbers in the Play Console's symbolicated stack traces.
If your project builds an APK, apply the build.gradle
build setting shown earlier to generate the native debug symbols file separately. Manually upload the native debug symbols file to the Google Play Panel. Every bit office of the build process, the Android Gradle plugin outputs this file in the following project location:
app/build/outputs/native-debug-symbols/variant-proper noun/native-debug-symbols.zip
Android Gradle plugin version 4.0 or before (and other build systems)
As role of the build process, the Android Gradle plugin keeps a copy of the unstripped libraries in a project directory. This directory structure is similar to the following:
app/build/intermediates/cmake/universal/release/obj/ ├── armeabi-v7a/ │ ├── libgameengine.so │ ├── libothercode.so │ └── libvideocodec.so ├── arm64-v8a/ │ ├── libgameengine.so │ ├── libothercode.so │ └── libvideocodec.so ├── x86/ │ ├── libgameengine.and so │ ├── libothercode.and then │ └── libvideocodec.so └── x86_64/ ├── libgameengine.so ├── libothercode.so └── libvideocodec.so
-
Naught upward the contents of this directory:
cd app/build/intermediates/cmake/universal/release/obj
nothing -r symbols.zilch .
-
Manually upload the
symbols.zippo
file to the Google Play Console.
Shrink your resource
Resource shrinking works simply in conjunction with code shrinking. After the code shrinker removes all unused lawmaking, the resource shrinker can identify which resources the app notwithstanding uses. This is peculiarly true when you add together code libraries that include resources—you must remove unused library code so the library resources become unreferenced and, thus, removable by the resource shrinker.
To enable resources shrinking, set the shrinkResources
holding to true
in your build.gradle
file (alongside minifyEnabled
for code shrinking). For case:
Groovy
android { ... buildTypes { release { shrinkResources truthful minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
Kotlin
android { ... buildTypes { getByName("release") { isShrinkResources = true isMinifyEnabled = true proguardFiles( getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" ) } } }
If y'all oasis't already congenital your app using minifyEnabled
for code shrinking, and so effort that earlier enabling shrinkResources
, considering you might need to edit your proguard-rules.pro
file to keep classes or methods that are created or invoked dynamically before y'all start removing resources.
Customize which resources to go along
If there are specific resources you wish to proceed or discard, create an XML file in your project with a <resources>
tag and specify each resources to keep in the tools:keep
attribute and each resources to discard in the tools:discard
attribute. Both attributes accept a comma-separated list of resources names. You can utilize the asterisk graphic symbol as a wild bill of fare.
For example:
<?xml version="i.0" encoding="utf-viii"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*" tools:discard="@layout/unused2" />
Salve this file in your project resources, for instance, at res/raw/keep.xml
. The build does not package this file into your app.
Specifying which resources to discard might seem silly when you lot could instead delete them, but this can be useful when using build variants. For example, you lot might put all your resources into the mutual project directory, then create a different keep.xml
file for each build variant when you know that a given resource appears to be used in lawmaking (and therefore non removed past the shrinker) but you know it actually won't be used for the given build variant. Information technology'due south likewise possible that the build tools incorrectly identified a resource equally needed, which is possible considering the compiler adds the resource IDs inline and and so the resource analyzer might not know the difference between a genuinely referenced resource and an integer value in the lawmaking that happens to have the same value.
Enable strict reference checks
Unremarkably, the resource shrinker tin can accurately determine whether a resource is used. However, if your code makes a call to Resources.getIdentifier()
(or if any of your libraries do that—the AppCompat library does), that means your code is looking up resource names based on dynamically-generated strings. When you lot practise this, the resource shrinker behaves defensively by default and marks all resources with a matching proper name format equally potentially used and unavailable for removal.
For example, the following code causes all resource with the img_
prefix to be marked as used.
Kotlin
val proper name = Cord.format("img_%1d", bending + 1) val res = resource.getIdentifier(name, "drawable", packageName)
Java
Cord name = String.format("img_%1d", angle + 1); res = getResources().getIdentifier(name, "drawable", getPackageName());
The resources shrinker also looks through all the cord constants in your code, besides equally diverse res/raw/
resource, looking for resource URLs in a format similar to file:///android_res/drawable//ic_plus_anim_016.png
. If it finds strings similar this or others that look similar they could be used to construct URLs like this, it doesn't remove them.
These are examples of the safe shrinking manner that is enabled by default. Y'all can, however, plow off this "better condom than pitiful" handling, and specify that the resource shrinker keep only resources that it'southward certain are used. To do this, set shrinkMode
to strict
in the go along.xml
file, as follows:
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:shrinkMode="strict" />
If you do enable strict shrinking manner and your lawmaking also references resources with dynamically-generated strings, as shown to a higher place, then you must manually keep those resources using the tools:keep
attribute.
Remove unused alternative resources
The Gradle resources shrinker removes only resource that are not referenced by your app code, which means information technology will non remove alternative resources for unlike device configurations. If necessary, you can employ the Android Gradle plugin's resConfigs
property to remove culling resource files that your app does not need.
For example, if you are using a library that includes language resources (such as AppCompat or Google Play Services), then your app includes all translated linguistic communication strings for the messages in those libraries whether the rest of your app is translated to the same languages or not. If you'd like to keep merely the languages that your app officially supports, you can specify those languages using the resConfig
holding. Whatsoever resources for languages not specified are removed.
The following snippet shows how to limit your language resources to just English language and French:
Groovy
android { defaultConfig { ... resConfigs "en", "fr" } }
Kotlin
android { defaultConfig { ... resourceConfigurations.addAll(listOf("en", "fr")) } }
When releasing an app using the Android App Bundle format, past default just languages configured on a user's device are downloaded when installing the app. Similarly, simply resource matching the device'southward screen density, and native libraries matching the device's ABI are included in the download. For more information refer to the Android App Packet configuration.
For legacy apps releasing with APKs (created earlier August 2021), you can customize which screen density or ABI resources to include in your APK by building multiple APKs that each target a different device configuration.
Merge indistinguishable resources
By default, Gradle besides merges identically named resources, such as drawables with the aforementioned name that might exist in different resources folders. This behavior is not controlled by the shrinkResources
property and cannot be disabled, because it is necessary to avoid errors when multiple resources friction match the name your lawmaking is looking up.
Resources merging occurs only when two or more files share an identical resource proper name, type, and qualifier. Gradle selects which file it considers to be the best choice among the duplicates (based on a priority order described below) and passes only that ane resources to the AAPT for distribution in the last antiquity.
Gradle looks for indistinguishable resource in the following locations:
- The main resources, associated with the main source set, generally located in
src/master/res/
. - The variant overlays, from the build blazon and build flavors.
- The library project dependencies.
Gradle merges duplicate resources in the following cascading priority order:
Dependencies → Main → Build flavor → Build blazon
For example, if a duplicate resources appears in both your main resources and a build flavour, Gradle selects the one in the build flavor.
If identical resource announced in the same source set, Gradle cannot merge them and emits a resources merge mistake. This can happen if you define multiple source sets in the sourceSet
property of your build.gradle
file—for example if both src/main/res/
and src/main/res2/
contain identical resources.
Obfuscate your code
The purpose of obfuscation is to reduce your app size past shortening the names of your app'south classes, methods, and fields. The post-obit is an example of obfuscation using R8:
androidx.appcompat.app.ActionBarDrawerToggle$DelegateProvider -> a.a.a.b: androidx.appcompat.app.AlertController -> androidx.appcompat.app.AlertController: android.content.Context mContext -> a int mListItemLayout -> O int mViewSpacingRight -> l android.widget.Button mButtonNeutral -> w int mMultiChoiceItemLayout -> M boolean mShowTitle -> P int mViewSpacingLeft -> j int mButtonPanelSideLayout -> K
While obfuscation does not remove code from your app, significant size savings tin be seen in apps with DEX files that alphabetize many classes, methods, and fields. Notwithstanding, equally obfuscation renames different parts of your code, certain tasks, such as inspecting stack traces, require boosted tools. To sympathize your stacktrace after obfuscation, read the next section about how to decode an obfuscated stack trace.
Additionally, if your code relies on predictable naming for your app'south methods and classes—when using reflection, for case, you should treat those signatures every bit entry points and specify continue rules for them, as described in the section about how to customize which code to keep. Those keep rules tell R8 to not only keep that lawmaking in your app's last DEX simply also retain its original naming.
Decode an obfuscated stack trace
Later R8 obfuscates your lawmaking, understanding a stack trace is difficult (if not impossible) because names of classes and methods might have been changed. Besides renaming, R8 can also modify the line numbers present in the stack traces to achieve additional size savings when writing the DEX files. Fortunately, R8 creates a mapping.txt
file each time information technology runs, which contains the obfuscated class, method, and field names mapped to the original names. This mapping file also contains data to map the line numbers dorsum to the original source file line numbers. R8 saves the file in the <module-name>/build/outputs/mapping/<build-type>/
directory.
To ensure that retracing stack traces is unambiguous, the following rules should exist added to your module'due south proguard-rules.pro
file:
-keepattributes LineNumberTable,SourceFile -renamesourcefileattribute SourceFile
The LineNumberTable
attribute is needed for disambiguating between optimized positions within methods. The SourceFile
attribute is necessary for getting line numbers printed in a stack trace on a virtual machine or device. -renamesourcefileattribute
will prepare the source file in stack traces to just SourceFile
. The actual original source file proper name is not required when retracing as the mapping file contains the original source file.
When publishing your app on Google Play, y'all can upload the mapping.txt
file for each version of your app. When publishing using Android App Bundles this file is included automatically every bit part of the app bundle content. And then Google Play will deobfuscate incoming stack traces from user-reported issues so you can review them in the Play Console. For more than information, run across the Help Center article about how to deobfuscate crash stack traces.
To decode an obfuscated stack trace yourself, use the retrace command-line tool, which is bundled with the command-line tools package.
Code optimization
In order to compress your app fifty-fifty further, R8 inspects your lawmaking at a deeper level to remove more unused code or, where possible, rewrite your lawmaking to brand information technology less verbose. The post-obit are a few examples of such optimizations:
- If your code never takes the
else {}
branch for a given if/else statement, R8 might remove the code for theelse {}
co-operative. - If your code calls a method in but ane place, R8 might remove the method and inline it at the unmarried telephone call site.
- If R8 determines that a course has only one unique subclass, and the course itself is not instantiated (for example, an abstract base course only used by one concrete implementation class), and so R8 can combine the 2 classes and remove a form from the app.
- To learn more, read the R8 optimization web log posts by Jake Wharton.
R8 does not permit you to disable or enable discrete optimizations, or modify the behavior of an optimization. In fact, R8 ignores whatsoever ProGuard rules that effort to modify default optimizations, such every bit -optimizations
and - optimizationpasses
. This restriction is of import because, as R8 continues to better, maintaining a standard behavior for optimizations helps the Android Studio team easily troubleshoot and resolve whatever issues that you lot might encounter.
Enable more aggressive optimizations
R8 includes a set of boosted optimizations that are non enabled past default. Y'all tin can enable these additional optimizations past including the following in your project's gradle.properties
file:
android.enableR8.fullMode=truthful
Because the additional optimizations make R8 comport differently from ProGuard, they may require you to include additional ProGuard rules to avoid runtime issues. For example, say that your code references a class through the Java Reflection API. By default, R8 assumes that you intend to examine and manipulate objects of that class at runtime—even if your lawmaking actually does not—and information technology automatically keeps the class and its static initializer.
However, when using "full mode", R8 does not make this assumption and, if R8 asserts that your code otherwise never uses the class at runtime, information technology removes the class from your app'southward final DEX. That is, if yous desire to keep the grade and its static initializer, you need to include a keep dominion in your rules file to do that.
If you come across whatever issues while using R8's "full mode", refer to the R8 FAQ folio for a possible solution. If you are unable to resolve the issue, please report a problems.
Troubleshoot with R8
This section describes some strategies for troubleshooting bug when enabling shrinking, obfuscation, and optimization using R8. If you lot practise not find a solution to your upshot beneath, also read the R8 FAQ page and ProGuard's troubleshooting guide.
Generate a report of removed (or kept) lawmaking
To help you troubleshoot certain R8 bug, it may be useful to come across a report of all the lawmaking that R8 removed from your app. For each module for which you want to generate this study, add -printusage <output-dir>/usage.txt
to your custom rules file. When yous enable R8 and build your app, R8 outputs a report with the path and file name you specified. The report of removed code looks like to the following:
androidx.drawerlayout.R$attr androidx.vectordrawable.R androidx.appcompat.app.AppCompatDelegateImpl public void setSupportActionBar(androidx.appcompat.widget.Toolbar) public boolean hasWindowFeature(int) public void setHandleNativeActionModesEnabled(boolean) android.view.ViewGroup getSubDecor() public void setLocalNightMode(int) concluding androidx.appcompat.app.AppCompatDelegateImpl$AutoNightModeManager getAutoNightModeManager() public last androidx.appcompat.app.ActionBarDrawerToggle$Consul getDrawerToggleDelegate() private static final boolean DEBUG individual static last java.lang.String KEY_LOCAL_NIGHT_MODE static final java.lang.String EXCEPTION_HANDLER_MESSAGE_SUFFIX ...
If instead you want to come across a report of the entry points that R8 determines from your project's keep rules , include -printseeds <output-dir>/seeds.txt
in your custom rules file. When you enable R8 and build your app, R8 outputs a report with the path and file name y'all specified. The study of kept entry points looks similar to the following:
com.example.myapplication.MainActivity androidx.appcompat.R$layout: int abc_action_menu_item_layout androidx.appcompat.R$attr: int activityChooserViewStyle androidx.appcompat.R$styleable: int MenuItem_android_id androidx.appcompat.R$styleable: int[] CoordinatorLayout_Layout androidx.lifecycle.FullLifecycleObserverAdapter ...
Troubleshoot resource shrinking
When you compress resource, the Build window shows a summary of the resources that are removed from the app. (You need to get-go click Toggle view on the left side of the window to display detailed text output from Gradle.) For example:
:android:shrinkDebugResources Removed unused resources: Binary resource data reduced from 2570KB to 1711KB: Removed 33% :android:validateDebugSigning
Gradle besides creates a diagnostic file named resources.txt
in <module-name>/build/outputs/mapping/release/
(the aforementioned folder as ProGuard'southward output files). This file includes details such as which resources reference other resource and which resources are used or removed.
For instance, to notice out why @drawable/ic_plus_anim_016
is still in your app, open the resources.txt
file and search for that file proper noun. You lot might find that it's referenced from another resource, as follows:
16:25:48.005 [Tranquillity] [system.out] @drawable/add_schedule_fab_icon_anim : reachable=true sixteen:25:48.009 [Serenity] [system.out] @drawable/ic_plus_anim_016
Y'all now need to know why @drawable/add_schedule_fab_icon_anim
is reachable—and if you search upwardly you lot'll discover that resource is listed under "The root reachable resource are:". This means in that location is a lawmaking reference to add_schedule_fab_icon_anim
(that is, its R.drawable ID was institute in the reachable code).
If you lot are non using strict checking, resource IDs can be marked as reachable if at that place are string constants that look similar they might be used to construct resource names for dynamically loaded resources. In that instance, if you search the build output for the resources proper noun, you lot might discover a message like this:
ten:32:l.590 [QUIET] [system.out] Marker drawable:ic_plus_anim_016:2130837506 used considering it format-string matches string puddle constant ic_plus_anim_%one$d.
If y'all come across one of these strings and yous are certain that the cord is non existence used to load the given resource dynamically, y'all tin can use the tools:discard
attribute to inform the build organisation to remove information technology, as described in the section virtually how to customize which resources to go on.
Source: https://developer.android.com/studio/build/shrink-code
0 Response to "how to verify crashlytics upload proguard mapping file"
Post a Comment