ProGuard
The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and methods with semantically obscure names. The result is a smaller sized .apk
file that is more difficult to reverse engineer. Because ProGuard makes your application harder to reverse engineer, it is important that you use it when your application utilizes features that are sensitive to security like when you are Licensing Your Applications.
ProGuard工具可以对代码进行 优化,压缩,混淆 从而加大反编译的难度。
ProGuard is integrated into the Android build system, so you do not have to invoke it manually. ProGuard runs only when you build your application in release mode, so you do not have to deal with obfuscated code when you build your application in debug mode. Having ProGuard run is completely optional, but highly recommended.
ProGuard工具只在release版本有效,并且已经被整合进android构建apk系统,不需要程序员手动操作。
This document describes how to enable and configure ProGuard as well as use the retrace
tool to decode obfuscated stack traces.
Enabling ProGuard (Gradle Builds)
When you create a project in Android Studio or with the Gradle build system, the minifyEnabled
property in the build.gradle
file enables and disables ProGuard for release builds. The minifyEnabled
property is part of the buildTypes
release
block that controls the settings applied to release builds. Set the minifyEnabled
property totrue
to enable ProGuard, as shown in this example.
在android studio下开启ProGuard 示例
android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
The getDefaultProguardFile('proguard-android.txt')
method obtains the default ProGuard settings from the Android SDK tools/proguard/
folder. The proguard-android-optimize.txt
file is also available in this Android SDK folder with the same rules but with optimizations enabled. ProGuard optimizations perform analysis at the bytecode level, inside and across methods to help make your app smaller and run faster. Android Studio adds the proguard-rules.pro
file at the root of the module, so you can also easily add custom ProGuard rules specific to the current module.
proguard的默认设置 母体 在 SDK tools/proguard/ 下
You can also add ProGuard files to the getDefaultProguardFile
directive for all release builds or as part of the productFlavor
settings in the build.gradle
file to customize the settings applied to build variants. This example adds the proguard-rules-new.pro
to the proguardFiles
directive and the other-rules.pro
file to the flavor2
product flavor.
android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'proguard-rules-new.pro' } } productFlavors { flavor1 { } flavor2 { proguardFile 'other-rules.pro' } } }
Configuring ProGuard
For some situations, the default configurations in the ProGuard configuration file will suffice. However, many situations are hard for ProGuard to analyze correctly and it might remove code that it thinks is not used, but your application actually needs. Some examples include:
通常情况下,默认的proguard 配置就够用。但下面3种情况下,proguard工具不能直接准确分析,可能会删掉它认为不用的代码。
- a class that is referenced only in the
AndroidManifest.xml
file - a method called from JNI
- dynamically referenced fields and methods
The default ProGuard configuration file tries to cover general cases, but you might encounter exceptions such as ClassNotFoundException
, which happens when ProGuard strips away an entire class that your application calls.
You can fix errors when ProGuard strips away your code by adding a -keep
line in the ProGuard configuration file. For example:
有时会遇到ClassNotFoundException错误,可用下面方法解决。
-keep public class <MyClass>
There are many options and considerations when using the -keep
option, so it is highly recommended that you read the ProGuard Manual for more information about customizing your configuration file. The Overview of Keep options and Examples sections are particularly helpful. The Troubleshootingsection of the ProGuard Manual outlines other common problems you might encounter when your code gets stripped away.
优化示例
Decoding Obfuscated Stack Traces(解码被puguard混淆的代码)
When your obfuscated code outputs a stack trace, the method names are obfuscated, which makes debugging hard, if not impossible. Fortunately, whenever ProGuard runs, it outputs a mapping.txt
file, which shows you the original class, method, and field names mapped to their obfuscated names.
使用ProGuard工具优化时,会在目录下生成一个mapping.txt文件,它记录了类,方法,属性 混淆前后的对应名。
The retrace.bat
script on Windows or the retrace.sh
script on Linux or Mac OS X can convert an obfuscated stack trace to a readable one. It is located in the <sdk_root>/tools/proguard/
directory. The syntax for executing theretrace
tool is:
<sdk_root>/tools/proguard/
retrace.sh 命令可以利用mapping.txt还原一个已混淆的类,方法,属性等。
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
For example:
解混淆示例
retrace.bat -verbose mapping.txt obfuscated_trace.txt
If you do not specify a value for <stacktrace_file>, the retrace
tool reads from standard input.
Debugging considerations for published applications
Save the mapping.txt
file for every release that you publish to your users. By retaining a copy of the mapping.txt
file for each release build, you ensure that you can debug a problem if a user encounters a bug and submits an obfuscated stack trace. A project's mapping.txt
file is overwritten every time you do a release build, so you must be careful about saving the versions that you need. The file is stored in the app build/outs/
folder.
For example, say you publish an application and continue developing new features of the application for a new version. You then do a release build using ProGuard soon after. The build overwrites the previous mapping.txt
file. A user submits a bug report containing a stack trace from the application that is currently published. You no longer have a way of debugging the user's stack trace, because the mapping.txt
file associated with the version on the user's device is gone. There are other situations where your mapping.txt
file can be overwritten, so ensure that you save a copy for every release that you anticipate you have to debug.
How you save the mapping.txt
files is your decision. For example, you can rename the files to include a version or build number, or you can version control them along with your source code.
为每一个发布的版本保存一个混淆对应关系的mapping.txt是个好习惯