代码混淆最好在项目开始阶段就开始,便于及时发现混淆后的代码问题。
可以在app/build.gradle中设置开启。
项目代码的混淆有套路:
1. 默认要添加的配置
-optimizationpasses 5 # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontskipnonpubliclibraryclasses #指定不去忽略非公共库的类
-dontskipnonpubliclibraryclassmembers#指定不去忽略非公共库的类
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-ignorewarning #这个会忽略所有警告,会有很多潜在的风险
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/* # 混淆时所采用的算法
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
2. 一般项目通用的保留
-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
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-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);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private 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();
}
-keep class **.R$* {
*;
}
-keepclassmembers class * {
void *(**On*Event);
}
3. 如果使用了WebView,需要添加:
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.webView, jav.lang.String);
}
4.特殊处理:
a) 处理反射类和方法。这类在代码中使用的比较少,如果有使用也容易处理
-keep class com.xx.xx.xx.xx.view.** { *; }
-keep class com.xx.xx.xx.xx.xx.** { *; }
b) 与js互相调用的类。这类一般是处理webView中的JS代码。
-keep class com.xx.xx.xx.xx.view.** { *; }
-keep class com.xx.xx.xx.xx.xx.** { *; }
c) 实体类,json解析类
-keep class com.xx.xx.entity.** { *; }
d) 最关键的就是: 三方依赖
如果使用了其他库的依赖,一定要引入对应的混淆规则。
比如使用了ButterKnife,就需要加入以下混淆规则
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * { @butterknife.* <fields>; }
-keepclasseswithmembernames class * { @butterknife.* <methods>; }