这里我们直接用Android Studio来说明如何进行混淆,Android Studio自身集成Java语言的ProGuard作为压缩,优化和混淆工具,配合Gradle构建工具使用很简单,只需要在工程应用目录的gradle文件中设置minifyEnabled为true即可。然后我们就可以到proguard-rules.pro文件中加入我们的混淆规则了。
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
先看如下两个比较常用的命令,很多童鞋可能会比较迷惑以下两者的区别。
//一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆
-keep class cn.hadcn.test.*
//两颗星表示把本包和所含子包下的类名都保持
-keep class cn.hadcn.test.**
用以上方法保持类后,你会发现类名虽然未混淆,但里面的具体方法和变量命名还是变了,这时如果既想保持类名,又想保持里面的内容不被混淆,我们就需要以下方法了
//一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆
-keep class cn.hadcn.test.* {*;}
//两颗星表示把本包和所含子包下的类名都保持
-keep class cn.hadcn.test.**{*;}
注:**可能会报语法错误,不过这对程序运行并不影响,如果想要去除警告可以用:
Alt+Enter来去掉警告即可
避免所有继承于?的类被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-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.preference.Preference
-keep public class * extends android.view.View
jni方法不可混淆,因为这个方法需要和native方法保持一致;
-keepclasseswithmembernames class * {
# 保持native方法不被混淆
native <methods>;
}
Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常;
-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆
public static final Android.os.Parcelable$Creator *;
}
使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用,见第二条规则。
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
保持特定类不被混淆,bean应用广泛,需要混淆
-keep class com.xy.z.HeBean{
public *;
}
保留我们自定义控件(继承自View)不被混淆
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
保留Parcelable序列化类不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
保留Serializable序列化的类不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
对于带有回调函数的onXXEvent、*OnListener的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
}
webView处理,项目中没有使用到webView忽略即可
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
参考资料有:
https://www.jianshu.com/p/7436a1a32891
https://blog.csdn.net/jinrumorijuesha/article/details/103239909
网友评论