ProGuard technology developed by Android

This article mainly refers to the book "App R&D Records", friends in need can refer to this book to learn more.

Introduction to ProGuard

ProGuard includes the following 4 functions in total, each of which is optional. We can decide which functions to execute through the configuration script. The execution flow of ProGuard is shown in the figure below.

  • Shrink: Detect and remove useless classes, fields, methods and attributes in the code.
  • Optimize: Optimize the bytecode and remove useless instructions.
  • Obfuscate: Use short and meaningless names such as a, b, c, and d to rename classes, fields, and methods.
  • Pre-check (Preveirfy): Pre-check the processed code on the Java platform.

Insert picture description here

ProGuard's obfuscation rules

The following is the most basic configuration information for confusion. Any app needs to use it and can be used as a template.

1. Basic instructions

  # 代码混淆压缩比,在07之间,默认为5,一般不需要改
    -optimizationpasses 5

 # 混淆时不使用大小写混合,混淆后的类名为小写,Windows操作系统必须加这一条,因为Windows系统对大小写不敏感
   -dontusemixedcaseclassnames

 # 指定不去忽略非公共的库的类
-dontskipnonpubliclibraryclasses

# 指定不去忽略非公共的库的类的成员
-dontskipnonpubliclibraryclassmembers

# 不做预校验,preverify是proguard的4个步骤之一
# Android不需要preverify,去掉这一步可加快混淆速度
-dontpreverify

# 有了verbose这句话,混淆后就会生成映射文件
# 包含有类名->混淆后类名的映射关系
# 然后使用printmapping指定映射文件的名称
-verbose
-printmapping proguardMapping.txt

# 指定混淆时采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不改变
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

# 保护代码中的Annotation不被混淆,这在JSON实体映射时非常重要,比如fastJson
-keepattributes *Annotation*

# 避免混淆泛型,这在JSON实体映射时非常重要,比如fastJson
-keepattributes Signature

//抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable

2. Things to keep

The following are just some examples, you can add what you need according to your needs.

# 保留所有的本地native方法不被混淆

-keepclasseswithmembernames class * {
    
    
    native <methods>;
}

# 保留了继承自Activity、Application这些类的子类
# 因为这些子类,都有可能被外部调用
# 比如说,第一行就保证了所有Activity的子类不要被混淆

-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
 
# 保留在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 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;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# 对于R(资源)下的所有类及其方法,都不能被混淆
//$表示的是内嵌类,内嵌类经常会被混淆,结果在调用的时候为空就会导致崩溃,最好的解决方法是把这个内嵌类拿出来,单独成为一个类。如果一定要内置,那么这个类就必须在混淆时进行保留。
-keep class **.R$* {
    
    
    *;
}

# 对于带有回调函数onXXEvent的,不能被混淆

-keepclassmembers class * {
    
    
    void *(**On*Event);
}

# 保留实体类和成员不被混淆

-keep public class com.youndheart.entity.** {
    
    

    public void set*(***);
    public *** get*();
    public *** is*();
}

3. Processing of WebView

# 对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)

}

#在app中与HTML5的JavaScript的交互进行特殊处理
#我们需要确保这些js要调用的原生方法不能够被混淆,于是我们需要做如下处理:
-keepclassmembers class com.ljd.example.JSInterface {
    
    
    <methods>;
}

4. Solutions for third-party Jar packages

  • Solution for android-support-v4.jar
-libraryjars libs/android-support-v4.jar

-dontwarn android.support.v4.**

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

-keep interface android.support.v4.app.** {
    
     *; }

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

-keep public class * extends android.app.Fragment
  • Solutions to other third-party jar packages
    Generally speaking, third-party jar packages have been obfuscated by progiard, and there are usually related instructions in the SDK documentation. What we need to do is to avoid these SDK classes and methods Be confused in our app.

Related reference link: https://www.jianshu.com/p/b5b2a5dfaaf4
https://blog.csdn.net/pang9998/article/details/83505980

Guess you like

Origin blog.csdn.net/qq_36828822/article/details/105897367