[Solved] Code obfuscation solution, adapted to AndroidX

Obfuscation in android Studio is basically the operation of the Proguard-rules.pro file. The process of confusion is also regular. Below I will introduce the obfuscation process in several parts.

(1) How to turn on confusion.

(2) Obfuscated public parts.

(3) Requires code that we don’t obfuscate.

(4) Obfuscation of third-party Jar packages under libs.

(5) The obfuscation method of complie’s third-party Jar package.

(6) Obfuscation of code comments.

How to enable obfuscation

Find the build.gradle of your project module in Android Studio, set minifyEnabled to true and it’s ok, as shown in the following figure:

How to write obfuscated code

#1. Basic command area
# Code obfuscation compression ratio, between 0 and 7, the default is 5, generally do not modify
-optimizationpasses 5

# Do not use case mixing when mixing, and the mixed class name is lowercase
-dontusemixedcaseclassnames

# Specify not to ignore non-public library classes
-dontskipnonpubliclibraryclasses

# Specify not to ignore class members of non-public libraries
-dontskipnonpubliclibraryclassmembers

# Do not optimize, it is recommended to use this option,
-dontoptimize

# Without pre-verification, preverify is one of the four steps of proguard. Android does not need preverify to speed up the obfuscation.
-dontpreverify

# After confusing our project, the mapping file contains the mapping relationship of class name -> obfuscated class name
-verbose

# Use printmapping to specify the name of the mapping file
-printmapping proguardMapping.txt

# suppress warnings
-ignorewarnings

# Specify the algorithm used for obfuscation, and the following parameter is a filter. This filter is an algorithm recommended by Google, and generally does not change
-optimizations !code/simplification/cast,!field/*,!class/merging/*

# Keep Annotation not confusing
-keepattributes *Annotation*

# Avoid confusing generics
-keepattributes Signature

# Keep code line numbers when throwing exceptions
-keepattributes SourceFile,LineNumberTable
#2. Default reserved area
# Keep the four components we use, custom Application, etc. these classes are not confused
# Because these subclasses may be called externally
-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 public class com.google.vending.licensing.ILicensingService
# Keep all classes under support and their inner classes
-keep class android.support.** {*;}
# keep inherited
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**

# Keep local native methods from being obfuscated
-keepclasseswithmembernames class * {
    native <methods>;
}

# The method parameter reserved in the Activity is the view method, so that the onClick we wrote in the layout will not be affected
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}

# Keep enum classes from being obfuscated
-keepclassmembers enum *{
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# Keep our custom controls (inherited from View) from being confused
-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 Parcelable serialization classes from being obfuscated
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

# Keep Serializable serialized classes from being obfuscated
-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();
}

# Reserve the resources under R
-keep class **.R$* {
 *;
}

# For onXXEvent and **On*Listener with callback functions, it cannot be confused
-keepclassmembers class * {
    void *(**On*Event);
    void *(**On*Listener);
}

# Avoid confusion of onclick method (android:onclick="onClick") in layout
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}

#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, java.lang.String);
}
#Special handling for interaction with HTML5 JavaScript in the app
#We need to ensure that the native methods to be called by these js cannot be confused, so we need to do the following:
#-keepclassmembers class com.XXX.XXX.JSInterface {
# <methods>;
#}
# AndroidX obfuscation
-keep class com.google.android.material.** {*;}
-keep class androidx.** {*;}
-keep public class * extends androidx.**
-keep interface androidx.** {*;}
-dontwarn com.google.android.material.**
-dontnote com.google.android.material.**
-dontwarn androidx.**
# Entity class defined in your own project
-keep class com.XXX.bean.** { *; }
-keep class com.XXX.widget.** { *; }
-keep class com.XXX.utils.** { *; }
-keep class com.XXX.base.** { *; }
#Third-party framework
#ButterKnife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

# EventBus
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

# PictureSelector
-keep class com.luck.picture.lib.** { *; }
-dontwarn com.yalantis.ucrop**
-keep class com.yalantis.ucrop** { *; }
-keep interface com.yalantis.ucrop** { *; }
-dontwarn org.codehaus.mojo.animal_sniffer.*

# zxing
-keep class com.google.zxing.{ *;}
-dontwarn com.google.zxing.**
-dontwarn en.bingoogolapple.**
-keep class cn.bingoogolapple.*{ *;}

#Glide
-dontwarn com.bumptech.glide.**
-keep class com.bumptech.glide.**{*;}
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

#Gson
-dontwarn sun.misc.**
-keep class com.google.gson.examples.android.model.** { <fields>; }
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

# OkHttp3
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**

#Retrofit
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
-keepattributes Exceptions
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }

# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
    long producerIndex;
    long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
-dontnote rx.internal.util.PlatformDependent


# WeChat Pay
-dontwarn com.tencent.mm.**
-dontwarn com.tencent.wxop.stat.**
-keep class com.tencent.mm.** {*;}
-keep class com.tencent.wxop.stat.**{*;}

# Alipay Wallet
-dontwarn com.alipay.**
-dontwarn HttpUtils.HttpFetcher
-dontwarn com.ta.utdid2.**
-dontwarn com.ut.device.**
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
-keep class com.alipay.mobilesecuritysdk.*
-keep class com.ut.*

# banner
-dontwarn com.youth.banner.**
-keep class com.youth.banner.**{*;}

# loading
-keep class com.wang.avi.** { *; }
-keep class com.wang.avi.indicators.** { *; }

# JPTabBar
-keep class com.jpeng.** {*;}

#SmartRefreshLayout
-keep class com.scwang.** {*;}

# Universal Adapter BaseRecyclerViewAdapterHelper
-keep class com.chad.library.adapter.** {
*;
}
-keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter
-keep public class * extends com.chad.library.adapter.base.BaseViewHolder
-keepclassmembers public class * extends com.chad.library.adapter.base.BaseViewHolder {
     <init>(android.view.View);
}

#youmeng
-keep class com.umeng.**{*;}
#You can join this confusion if you integrate U-APM products
-keep class com.uc.**{*;}
-keepclassmembers class*{
public<init>(org.json.JSONObject);
}
-keepclassmembers enum*{
publicstatic**[] values();
publicstatic** valueOf(java.lang.String);
}

# screen adaptation
-keep class me.jessyan.autosize.** { *; }
-keep interface me.jessyan.autosize.** { *; }

# new version update
-dontwarn com.king.app.updater.**
-keep class com.king.app.updater.**{ *;}
-keep class * extends com.king.app.updater.**{ *;}
-keep class * implements com.king.app.updater.**{ *;}
-keepattributes InnerClasses
-dontwarn com.king.app.dialog.**
-keep class com.king.app.dialog.**{ *;}

#shareSDK
-keep class cn.sharesdk.**{*;}
-keep class com.sina.**{*;}
-keep class com.mob.**{*;}
-keep class com.bytedance.**{*;}
-dontwarn cn.sharesdk.**
-dontwarn com.sina.**
-dontwarn com.mob.**

-keep class androidx.recyclerview.widget.**{*;}
-keep class androidx.viewpager2.widget.**{*;}

From: Android Development Practice – Code Obfuscation Solution, Adapting to AndroidX – Master Jin’s Dream – Blog Park (cnblogs.com)