前言
在应用发布前,就需要对代码进行混淆处理,从而让我们代码即使被反编译,也难以阅读; 很多人不知道怎么设置混淆,哪些不需要混淆,那来了老铁们,可以直接拿来用的知识点。
AS中混淆配置
在AS中可以通过配置proguard-rules.pro
文件,对生成的apk
和jar
进行加密,另外还需要配置项目中 app下的 build.gradle 来开启混淆功能。
AS中项目混淆配置
gradle中代码如下,直接拿来用
buildTypes {
debug {
minifyEnabled false // 混淆
zipAlignEnabled true // Zipalign优化
shrinkResources true // 移除无用的resource文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 加载默认混淆配置文件
signingConfig signingConfigs.debug // 签名
}
release {
minifyEnabled true // 混淆
zipAlignEnabled true // Zipalign优化
shrinkResources true // 移除无用的resource文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 加载默认混淆配置文件
signingConfig signingConfigs.relealse // 签名
}
}
复制代码
规则
混淆会用无意义的短变量去重命名类、变量、方法,但是对于外部的一些引用是通过名字找到对应的方法和类。混淆过后通过原来的名字去找混淆后的名字,是找不到对应方法和类,就会出异常报错。所以有些情况是不能进行混淆的。
- 自定义控件不进行混淆
- 枚举类不被混淆
- 反射类不进行混淆
- 实体类不被混淆
- JS调用的Java方法
- 四大组件不进行混淆
- JNI中调用类不进行混淆
- Layout布局使用的
View
构造函数、android:onClick
等 Parcelable
的子类和Creator
静态成员变量不混淆
混淆文件内容
基本混淆指令
# 设置混淆的压缩比率 0 ~ 7
-optimizationpasses 5
# 混淆时不使用大小写混合,混淆后的类名为小写
-dontusemixedcaseclassnames
# 指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses
# 指定不去忽略非公共库的成员
-dontskipnonpubliclibraryclassmembers
# 混淆时不做预校验
-dontpreverify
# 混淆时不记录日志
-verbose
# 忽略警告
-ignorewarning
# 代码优化
-dontshrink
# 不优化输入的类文件
-dontoptimize
# 保留注解不混淆
-keepattributes *Annotation*,InnerClasses
# 避免混淆泛型
-keepattributes Signature
# 保留代码行号,方便异常信息的追踪
-keepattributes SourceFile,LineNumberTable
# 混淆采用的算法
-optimizations !code/simplification/cast,!field/*,!class/merging/*
# dump.txt文件列出apk包内所有class的内部结构
-dump class_files.txt
# seeds.txt文件列出未混淆的类和成员
-printseeds seeds.txt
# usage.txt文件列出从apk中删除的代码
-printusage unused.txt
# mapping.txt文件列出混淆前后的映射
-printmapping mapping.txt
复制代码
不需混淆的Android类
support design库、support下的所有类及其内部类、Android类
-keep public class * extends android.app.Fragment
-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.preference.Preference
-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.** {*;}
-dontwarn android.support.**
-keep interface android.support.** { *; }
-keep class androidx.** {*;}
-keep interface androidx.** {*;}
-keep public class * extends androidx.**
-dontwarn androidx.**
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }
-keep class com.google.android.material.** {*;}
-dontwarn com.google.android.material.**
-dontnote com.google.android.material.**
复制代码
避免混淆自定义控件类的 get/set 方法和构造函数
-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);
}
复制代码
关闭 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(...);
}
复制代码
避免资源混淆
-keep class **.R$* {*;}
复制代码
避免layout中onclick方法
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
复制代码
避免混淆枚举类
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
复制代码
Natvie 方法不混淆
-keepclasseswithmembernames class * {
native <methods>;
}
复制代码
避免Parcelable混淆和Serializable接口
-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;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
复制代码
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);
}
-keep public class [包名.类名]$[内部类]{
public *;
}
-keepattributes JavascriptInterface
复制代码
网络框架OkHttp3混淆配置
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
作者:Android开发编程
链接:https://juejin.cn/post/6966106746649575460
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。