【Android】【代码混淆】ProGuard

时间:2021-07-28 04:38:20

proguard介绍

1. proguard 官网

2. 代码混淆技术ProGuard

3. [译] ProGuard 选项

4. Proguard的Keep使用方法

5. Android 混淆打包不混淆第三方jar包

6. 官方文档翻译

7. Proguard 相关(不错)




还原混淆

1. 还原混淆后log方法

2. 解码混淆文件



遇到的问题:

1. json 问题

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to ***


2. eventbus 问题

de.greenrobot.event.EventBusException: Subscriber class *** and its super classes have no public methods with the @Subscribe annotation


解决方法:

主要是这句中指定的对应属性

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

3.  webview JavascriptInterface 问题

点击打开链接

addJavascriptInterface的整个方法为 

android.webkit.WebView.addJavascriptInterface(Object object, String name)

一般的例子如下:

webView.addJavascriptInterface(new MyJavaScriptInterface(), "myContent");

其中MyJavaScriptInterface是内部类:

public class MyJavaScriptInterface {
@JavascriptInterface
public String getContent() {
return content;
}
}


然后我们需要将MyJavaScriptInterface在混淆脚本中声明,否则就无法调用。

-keepattributes *Annotation*

-keepattributes *JavascriptInterface*

-keepclassmembers class 包名$MyJavaScriptInterface {
   public *;
}





附个完整的:

# 压缩配置
-dontshrink


# 优化配置
# 不优化输入的类文件
-dontoptimize


# 混淆配置
# 混淆时不使用大小写混合,混淆后的类名为小写
-dontusemixedcaseclassnames
# 包含有类名->混淆后类名的映射关系,输出原始的类,方法和字段名与混淆后代码间的映射
# 然后使用printmapping指定映射文件的名称
-printmapping proguard-mapping.txt

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

# 预校验配置
# 不做预校验
# -dontpreverify


# General options
-verbose


#############################################################################


# 对三方jar包不混淆

-libraryjars libs/volley.jar

-libraryjars libs/gson-2.8.1.jar

-libraryjars libs/eventbus-3.0.0.jar

-libraryjars libs/glide-3.7.0.jar


# keep options
#【不进行混淆保持原样】
-keep public class * extends android.app.Activity
-keep public class * extends android.preference.PreferenceActivity

-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.view.View
-keep public class * extends android.app.Fragment

-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v13.**

-keep class android.support.v4.** { *; }
-keep class android.support.v13.app.** { *; }


# 保留所有的本地native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}

# 保留在Activity中的方法参数是view的方法,
# 从而我们在layout里面编写onClick就不会被影响
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}


# 枚举类不能被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}


# 保留自定义控件(继承自View)不被混淆
-keep 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 {
*;
}


# 对于R(资源)下的所有类及其方法,都不能被混淆
-keep class **.R$* {
*;
}


# 对于带有回调函数onXXEvent的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
}


# WebView的处理
-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, java.lang.String);
}


#aidl子类
-keep class * extends android.os.IInterface {
public protected <methods>;
}