作者:郭嘉
邮箱:allenwells@163.com
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWells
本文主要介绍Android应用程序APK的混淆方式。下面会以图文的形式,详尽的叙述eclipse下ProGuard的使用方法。
一 ProGuard配置文件引用
eclipse中的Android工程会有以下两个文件(较早版本的ADT是proguard.cfg文件),如图所示:
- proguard-project.txt:代码混淆配置文件。
- project.properties:Android工程属性文件,用来引用proguard-project.txt文件作代码混淆。
proguard-project.txt配置文件,初始没有任何配置选项,如下图所示:
project.properties工程属性文件,如图中红框所示,指定了两个ProGuard的配置文件,系统默认配置文件proguard-android.txt和自定义配置文件proguard-project.txt。
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
这样显得有些繁琐了,后续会把所有的配置都写在一个文件里,命名为proguard-for-apk.txt,在project.properties文件中,用以下方式引用它。
proguard.config=proguard-for-apk.txt
二 ProGuard配置文件书写
配置文件的书写因工程而异,下面给出一些常见的配置选项,并作说明。
2.1 参数选项配置
#指定不去使用混淆的类名
-dontusemixedcaseclassnames
#指定不去忽略非公共的库类
-dontskipnonpubliclibraryclasses
-verbose
-ignorewarnings
# 支持库包含对新平台的版本,这些版本是安全的,无需发出警告。
-dontwarn android.support.**
2.2 保留选项配置
#指定保留Annotation
-keepattributes *Annotation*
#指定保留JavaScript接口方法
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
-keepclassmembers class fqcn.of.javascript.interface.for.webview
{
public *;
}
#指定保留需要在AndroidManifest.xml文件中注册的组件
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
#指定保留在布局文件中注册的方法,比如onclick属性等
-keepclassmembers class * extends android.content.Context {
public void *(android.view.View);
public void *(android.view.MenuItem);
}
#指定保留需要Context和AttributeSet进行构造的类
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# 指定保留本地方法名和它们的类
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# 枚举类也应该被保留。
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
#保留所有具有公有访问权限的类和其公共成员
-keepclasseswithmembers class *{
public *;
}
# 指定保留保留实现了Parcelable接口类中的静态变量
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
#指定保留静态变量
-keepclassmembers class **.R$* {
public static <fields>;
}
#指定其他需要保留的类,比如某些通过Class.forName等方式动态创建的类。
# -keep public class mypackage.MyClass
# -keep public interface mypackage.MyInterface
# -keep public class * implements mypackage.MyInterface
#指定保留所有Serialization和Parcelable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keepclassmembers class * implements android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
2.3 压缩选项配置
2.4 优化选项配置
#删除Log代码
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
#指定不去优化
-dontoptimize
#指定不去校验
-dontpreverify
2.5 混淆选项配置
以上说明 的配置文件,点此下载,欢迎大家反馈交流。
“`