一、混淆的意義
混淆程式碼並不是讓程式碼無法被反編譯,而是將程式碼中的類、方法、變數等資訊進行重新命名,把它們改成一些毫無意義的名字,同時也可以移除未被使用的類、方法、變數等。 所以直觀的看,透過混淆可以提高程式的安全性,增加逆向工程的難度,同時也有效縮減了apk的體積。總結如下:
1、將專案中的類、方法、變數等資訊進行重新命名,變成一些無意義的簡短名字。
2、移除未被使用的類、方法、變數等。
二、混淆的規則和配置
凡是需要在AndroidManifest.xml中去註冊的所有類的類名以及從父類重寫的方法名都自動不會被混淆。 因此,除了Activity之外,這份規則同樣也適用於Service、BroadcastReceiver和ContentProvider。
(1)minifyEnabled
minifyEnabled為true的作用:啟用程式碼混淆、壓縮APK;
minifyEnabled會對資源進行壓縮,多餘的程式碼在打包的時候就給移除掉了。不僅僅是程式碼,沒有被呼叫的資源同樣也會被移除掉,因此minifyEnabled除了混淆程式碼之外,還可以起到壓縮APK包的作用。
開啟混淆後也可新增shrinkResources,表示開啟刪除無用資源。
(2)shrinkResources
shrinkResources為true用來開啟刪除無用資源。
shrinkResources會對就是沒有被引用的檔案(經過實測是drawable,layout,實際並不是徹底刪除,而是保留檔名,但是沒有內容),但是因為需要知道是否被引用所以需要配合mififyEnable使用,只有當兩者都為true的時候才會起到真正的刪除無效程式碼和無引用資源的目的。
(3)避免被誤刪除
若配置minifyEnable true && shrinkResources true,防止避免誤刪除的檔案,可以配置如下: 在res/raw/keep.xml(避免被誤刪除)寫了配置的
對於沒有被引用的檔案&沒有在配置檔案keep.xml中宣告儲存的檔案,打包後是沒有內容的,宣告儲存的檔案有內容(資原始檔和layout檔案)。 注意:string.xml中沒有被引用的怎麼設定都不會被刪除。
(4)proguard-android.txt和proguard-rules.pro
proguard-android.txt:代表系統預設的混淆規則配置檔案,該檔案在/tools/proguard下,一般不要更改該配置檔案,因為也會作用於其它專案。
proguard-rules.pro:程式碼表當前Project的混淆配置檔案,在app module下,可以透過修改該檔案來新增適用當前專案的混淆規則。
(5)proguard資料夾
程式碼混淆生成apk之後,專案下面會多出來一個proguard資料夾,proguard資料夾中四個檔案的作用。
dump.txt : 描述了apk中所有類檔案中內部的結構體。
mapping.txt : 列出了原始的類、方法和名稱與混淆程式碼間的對映。
seeds.txt : 列出了沒有混淆的類和方法。
usage.txt : 列出congapk中刪除的程式碼。
android studio自帶java語言的ProGuard工具,主要用來壓縮、最佳化、混淆,然後配合Gradle構建工具實現混淆。
在app module中統一配置混淆規則
我們可以直接在app module中build.gradle檔案配置所有module需要混淆的規則。這樣,其他module中就無需開啟混淆。
首先在build.gradle 中將混淆的開關開啟,即 minifyEnabled 置為 true
1 buildTypes { 2 release { 3 minifyEnabled true //開啟混淆 4 zipAlignEnabled true //壓縮最佳化 5 shrinkResources true //移出無用資源 6 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //預設的混淆檔案以及我們指定的混淆檔案 7 } 8 }
如果是model混淆,子模組混淆檔案的指定是透過consumerProguardFiles這個屬性來指定的,並不是proguardFiles 屬性,而且我們無需配置其他的選項,只需要配置consumerProguardFiles屬性就可以。該屬性表示在打包的時候會自動尋找該module下我們指定的混淆檔案對程式碼進行混淆。配置如下:
1 buildTypes { 2 release { 3 //minifyEnabled true //是否開啟混淆,其實子模組中這個已經沒有作用了,由主模組控制 4 consumerProguardFiles 'proguard-rules.pro' //子模組要用這個命令才能生效 5 }
然後就要去proguard-rules.pro寫入我們的混淆的規則(如檔案其名),防止重要的類被混淆移除了。
先特別介紹的是與保持相關元素不參與混淆的規則相關的幾種命令:
-keep 防止類和成員被移除或者被重新命名
-keepnames 防止類和成員被重新命名
-keepclassmembers 防止成員被移除或者被重新命名
-keepclasseswithmembers 防止擁有該成員的類和成員被移除或者被重新命名
-keepclasseswithmembernames 防止擁有該成員的類和成員被重新命名
混淆規則:
1、有一些固定的混淆規則不需要更改:
#指定程式碼的壓縮級別
-optimizationpasses 5
#包明不混合大小寫
-dontusemixedcaseclassnames
#不去忽略非公共的庫類
-dontskipnonpubliclibraryclasses
#最佳化 不最佳化輸入的類檔案
-dontoptimize
#預校驗
-dontpreverify
#混淆時是否記錄日誌
-verbose
# 混淆時所採用的演算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保護註解
-keepattributes *Annotation*
2、理解萬用字元
-keep class cn.hadcn.test.**
-keep class cn.hadcn.test.*
很多同學都搞不懂下面兩個的區別,一顆星表示只是保持該包下的類名,而子包下的類名還是會被混淆;兩顆星表示把本包和所含子包下的類名都保持;用以上方法保持類後,你會發現類名雖然未混淆,但裡面的具體方法和變數命名還是變了,這時如果既想保持類名,又想保持裡面的內容不被混淆,我們就需要以下方法了:
-keep class cn.hadcn.test.* {*;}
3、保證指定包名下的所有類及子包中所有的類不被混淆
例子1:com.lib.manager 包下面的類不混淆
-keep class com.lib.manager.**{*;}
例子2:v4包下面的所有類不混淆
-keep class android.support.v4.** { *; }
4、保證指定的類不被混淆
例子1:YiBaWiFiActivity 類不被混淆, YiBaWiFiActivity 完整包名:com.yiba.wifi.sdk.lib.activity.YiBaWiFiActivity
-keep class com.yiba.wifi.sdk.lib.activity.YiBaWiFiActivity{*;}
例子2:v4 包下面的 ActivityCompat 類不被混淆
-keep class android.support.v4.app.ActivityCompat{*;}
5、不混淆指定類的子類
-keep class * extends pp.lib.User { *; }
User 類的子類不混淆
6、指定介面不混淆
Callback 是一個介面,完整包名為:com.lib.impl.Callback
-keep interface com.lib.impl.Callback{ * ; }
7、指定介面的實現類不混淆
Callback 是一個介面,完整包名為:com.lib.impl.Callback . 所有的實現類都不會混淆。
-keep class * implements com.lib.impl.Callback { *; }
8、指定類的內部類不混淆
PhoneUtil 的原始碼如下:
1 package com.lib.manager; 2 import android.content.Context; 3 import android.os.AsyncTask; 4 5 /** 6 * Created by yiba_zyj on 2017/4/5. 7 */ 8 9 public class PhoneUtil { 10 11 public final static int APPID = 100 ; 12 13 public PhoneUtil( Context context ){ 14 15 } 16 17 class MyTask extends AsyncTask { 18 19 @Override 20 protected Object doInBackground(Object[] params) { 21 return null; 22 } 23 } 24 }
PhoneUtil 有一個常量、一個建構函式、一個內部類。
混淆規則:
-keep class com.lib.manager.PhoneUtil$* {
* ;
}
9、建構函式不混淆
PhoneUtil 的原始碼如所示:
1 package com.lib; 2 3 /** 4 * Created by yiba_zyj on 2017/4/7. 5 */ 6 7 public class PhoneUtil { 8 9 public static final String aa = "1222" ; 10 11 public void run(){ 12 13 } 14 15 }
混淆規則:PhoneUtil 的無參建構函式不混淆 。PhoneUtil 裡面沒有用到的 屬性和方法將會被移除。
-keep class com.lib.PhoneUtil {
public <init>();
}
那麼有參的建構函式的混淆規則是怎麼樣的?
混淆規則:PhoneUtil 的 引數為 Context 的建構函式不混淆
-keep class com.lib.PhoneUtil {
public <init>( android.content.Context );
}
10、指定類的屬性和方法不被混淆
原始類 PhoneUtil 程式碼如下,完整的包名為:com.lib.manager.PhoneUtil
1 package com.lib.manager; 2 3 import android.content.Context; 4 import android.util.DisplayMetrics; 5 import android.view.WindowManager; 6 7 /** 8 * Created by yiba_zyj on 2017/4/5. 9 */ 10 11 public class PhoneUtil { 12 13 public static final int AppID = 100 ; 14 15 /** 16 * 獲得螢幕高度 17 * @param context 18 * @return 19 */ 20 public static int getScreenWidth(Context context) { 21 WindowManager wm = (WindowManager) context 22 .getSystemService(Context.WINDOW_SERVICE); 23 DisplayMetrics outMetrics = new DisplayMetrics(); 24 wm.getDefaultDisplay().getMetrics(outMetrics); 25 return outMetrics.widthPixels; 26 } 27 28 /** 29 * 獲得螢幕寬度 30 * @param context 31 * @return 32 */ 33 public static int getScreenHeight(Context context) { 34 WindowManager wm = (WindowManager) context 35 .getSystemService(Context.WINDOW_SERVICE); 36 DisplayMetrics outMetrics = new DisplayMetrics(); 37 wm.getDefaultDisplay().getMetrics(outMetrics); 38 return outMetrics.heightPixels; 39 } 40 41 }
PhoneUtil 類中包含1個常量及2個方法.類中的變數不被混淆:
-keep class com.lib.manager.PhoneUtil{
public static final int AppID ;
}
混淆後的效果如下:
1 package com.lib.manager; 2 3 public class PhoneUtil { 4 public static final int AppID = 100; 5 6 public PhoneUtil() { 7 } 8 }
可以看到混淆後的類中,AppID 常量被儲存下來了,getScreenWidth 、 getScreenHeight 這兩個方法被移除了。 為什麼會有方法被移除? 因為在混淆時,Android 會預設移除沒有使用的的方法和資源,保證apk 合理的被壓縮。保留類中的方法不被混淆
-keep class com.lib.manager.PhoneUtil{
public static int getScreenWidth(android.content.Context);
}
混淆後的方法如下:
1 // 2 // Source code recreated from a .class file by IntelliJ IDEA 3 // (powered by Fernflower decompiler) 4 // 5 6 package com.lib.manager; 7 8 import android.content.Context; 9 import android.util.DisplayMetrics; 10 import android.view.WindowManager; 11 12 public class PhoneUtil { 13 public PhoneUtil() { 14 } 15 16 public static int getScreenWidth(Context var0) { 17 WindowManager var1 = (WindowManager)var0.getSystemService("window"); 18 DisplayMetrics var2 = new DisplayMetrics(); 19 var1.getDefaultDisplay().getMetrics(var2); 20 return var2.widthPixels; 21 } 22 }
11、不混淆類中所有的 public 方法
# <methods> 匹配所有的方法
-keep class cn.hadcn.test.One {
public <methods>;
}
表示One類下的所有public方法都不會被混淆
12、不混淆類中所有的 public 欄位
-keep class pp.lib.PhoneUtil{
public <fields> ;
}
表示 PhoneUtil 類中所有的 public 屬性將保留,其他型別的欄位
13、不混淆建構函式
-keep class pp.lib.PhoneUtil{
<init>(***) ;
<init>(*** , *** ) ;
}
不混淆 PhoneUtil 類中所有 一個引數 和 兩個引數的 的建構函式。
13、不混淆 bean 物件裡面的 set 、get 方法
User 物件如下圖所示:
1 package pp.lib; 2 3 /** 4 * Created by ${zhaoyanjun} on 2017/4/10. 5 */ 6 7 public class User { 8 9 private String name ; 10 private String age ; 11 12 public String getName() { 13 return name; 14 } 15 16 public void setName(String name) { 17 this.name = name; 18 } 19 20 public String getAge() { 21 return age; 22 } 23 24 public void setAge(String age) { 25 this.age = age; 26 } 27 }
混淆規則:不混淆 User 類中所有的 set 和 get 方法,*** 代表 萬用字元
-keep class pp.lib.User{
void set*( *** ) ;
*** get*() ;
}
常見不混淆的類和屬性
不混淆四大元件 和 Application
因為四大元件和 Application 需要在 AndroidManifest.xml 中註冊,不能混淆,否則就會報類找不到異常。
-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
特殊情況:
如果 BroadcastReceiver 是動態註冊的,則是可以加入混淆的。
不混淆任何包含native方法的類的類名以及native方法名
-keepclasseswithmembernames class * {
native <methods>;
}
不混淆任何一個View中的setXxx()和getXxx()方法,因為屬性動畫需要有相應的setter和getter的方法實現,混淆了就無法工作了。
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
不混淆Activity中引數是View的方法,因為有這樣一種用法,在XML中配置android:onClick=”buttonClick”屬性,當使用者點選該按鈕時就會呼叫Activity中的buttonClick(View view)方法,如果這個方法被混淆的話就找不到了。
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
不混淆列舉中的values()和valueOf()方法
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
不混淆Parcelable實現類中的CREATOR欄位,毫無疑問,CREATOR欄位是絕對不能改變的,包括大小寫都不能變,不然整個Parcelable工作機制都會失敗。
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}
不混淆R檔案中的所有靜態欄位,我們都知道R檔案是透過欄位來記錄每個資源的id的,欄位名要是被混淆了,id也就找不著了。
登入後複製
-keepclassmembers class **.R$* {
public static <fields>;
}
其他的常見不被混淆
一般以下情況都會不混淆:
1.使用了自定義控制元件那麼要保證它們不參與混淆。
2.使用了列舉要保證列舉不被混淆。
3.對第三方庫中的類不進行混淆。
4.運用了反射的類也不進行混淆。
5.使用了 Gson 之類的工具要使 JavaBean 類即實體類不被混淆。
6.在引用第三方庫的時候,一般會標明庫的混淆規則的,建議在使用的時候就把混淆規則新增上去,免得到最後才去找。
7.有用到 WebView 的 JS 呼叫也需要保證寫的介面方法不混淆,原因和第一條一樣。
8.Parcelable 的子類和 Creator 靜態成員變數不混淆,否則會產生 Android.os.BadParcelableException 異常。
9.供第三放呼叫的Interface介面不進行混淆。
附一份配置:
1 # 指定程式碼的壓縮級別 0 - 7(指定程式碼進行迭代最佳化的次數,在Android裡面預設是5,這條指令也只有在可以最佳化時起作用。) 2 -optimizationpasses 5 3 # 混淆時不會產生形形色色的類名(混淆時不使用大小寫混合類名) 4 -dontusemixedcaseclassnames 5 # 指定不去忽略非公共的庫類(不跳過library中的非public的類) 6 -dontskipnonpubliclibraryclasses 7 # 指定不去忽略包可見的庫類的成員 8 -dontskipnonpubliclibraryclassmembers 9 #不進行最佳化,建議使用此選項, 10 -dontoptimize 11 # 不進行預校驗,Android不需要,可加快混淆速度。 12 -dontpreverify 13 # 遮蔽警告 14 -ignorewarnings 15 # 指定混淆是採用的演算法,後面的引數是一個過濾器 16 # 這個過濾器是谷歌推薦的演算法,一般不做更改 17 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 18 # 保護程式碼中的Annotation不被混淆 19 -keepattributes *Annotation* 20 # 避免混淆泛型, 這在JSON實體對映時非常重要 21 -keepattributes Signature 22 # 丟擲異常時保留程式碼行號 23 -keepattributes SourceFile,LineNumberTable 24 #最佳化時允許訪問並修改有修飾符的類和類的成員,這可以提高最佳化步驟的結果。 25 # 比如,當內聯一個公共的getter方法時,這也可能需要外地公共訪問。 26 # 雖然java二進位制規範不需要這個,要不然有的虛擬機器處理這些程式碼會有問題。當有最佳化和使用-repackageclasses時才適用。 27 #指示語:不能用這個指令處理庫中的程式碼,因為有的類和類成員沒有設計成public ,而在api中可能變成public 28 -allowaccessmodification 29 #當有最佳化和使用-repackageclasses時才適用。 30 -repackageclasses '' 31 # 混淆時記錄日誌(列印混淆的詳細資訊) 32 # 這句話能夠使我們的專案混淆後產生對映檔案 33 # 包含有類名->混淆後類名的對映關係 34 -verbose 35 # ----------------------------- 預設保留 ----------------------------- 36 # 保持哪些類不被混淆 37 #繼承activity,application,service,broadcastReceiver,contentprovider....不進行混淆 38 -keep public class * extends android.app.Activity 39 -keep public class * extends android.app.Application 40 -keep public class * extends android.support.multidex.MultiDexApplication 41 -keep public class * extends android.app.Service 42 -keep public class * extends android.content.BroadcastReceiver 43 -keep public class * extends android.content.ContentProvider 44 -keep public class * extends android.app.backup.BackupAgentHelper 45 -keep public class * extends android.preference.Preference 46 -keep public class * extends android.view.View 47 -keep class android.support.** {*;}## 保留support下的所有類及其內部類 48 -keep public class com.google.vending.licensing.ILicensingService 49 -keep public class com.android.vending.licensing.ILicensingService 50 #表示不混淆上面宣告的類,最後這兩個類我們基本也用不上,是接入Google原生的一些服務時使用的。 51 #---------------------------------------------------- 52 # 保留繼承的 53 -keep public class * extends android.support.v4.** 54 -keep public class * extends android.support.v7.** 55 -keep public class * extends android.support.annotation.** 56 #表示不混淆任何包含native方法的類的類名以及native方法名,這個和我們剛才驗證的結果是一致 57 -keepclasseswithmembernames class * { 58 native <methods>; 59 } 60 #這個主要是在layout 中寫的onclick方法android:onclick="onClick",不進行混淆 61 #表示不混淆Activity中引數是View的方法,因為有這樣一種用法,在XML中配置android:onClick=”buttonClick”屬性, 62 #當使用者點選該按鈕時就會呼叫Activity中的buttonClick(View view)方法,如果這個方法被混淆的話就找不到了 63 -keepclassmembers class * extends android.app.Activity{ 64 public void *(android.view.View); 65 } 66 #表示不混淆列舉中的values()和valueOf()方法,列舉我用的非常少,這個就不評論了 67 -keepclassmembers enum * { 68 public static **[] values(); 69 public static ** valueOf(java.lang.String); 70 } 71 #表示不混淆任何一個View中的setXxx()和getXxx()方法, 72 #因為屬性動畫需要有相應的setter和getter的方法實現,混淆了就無法工作了。 73 -keep public class * extends android.view.View{ 74 *** get*(); 75 void set*(***); 76 public <init>(android.content.Context); 77 public <init>(android.content.Context, android.util.AttributeSet); 78 public <init>(android.content.Context, android.util.AttributeSet, int); 79 } 80 -keepclasseswithmembers class * { 81 public <init>(android.content.Context, android.util.AttributeSet); 82 public <init>(android.content.Context, android.util.AttributeSet, int); 83 } 84 #表示不混淆Parcelable實現類中的CREATOR欄位, 85 #毫無疑問,CREATOR欄位是絕對不能改變的,包括大小寫都不能變,不然整個Parcelable工作機制都會失敗。 86 -keep class * implements android.os.Parcelable { 87 public static final android.os.Parcelable$Creator *; 88 } 89 # 這指定了繼承Serizalizable的類的如下成員不被移除混淆 90 -keepclassmembers class * implements java.io.Serializable { 91 static final long serialVersionUID; 92 private static final java.io.ObjectStreamField[] serialPersistentFields; 93 private void writeObject(java.io.ObjectOutputStream); 94 private void readObject(java.io.ObjectInputStream); 95 java.lang.Object writeReplace(); 96 java.lang.Object readResolve(); 97 } 98 # 保留R下面的資源 99 -keep class **.R$* { 100 *; 101 } 102 #不混淆資源類下static的 103 -keepclassmembers class **.R$* { 104 public static <fields>; 105 } 106 # 對於帶有回撥函式的onXXEvent、**On*Listener的,不能被混淆 107 -keepclassmembers class * { 108 void *(**On*Event); 109 void *(**On*Listener); 110 } 111 # 保留我們自定義控制元件(繼承自View)不被混淆 112 -keep public class * extends android.view.View{ 113 *** get*(); 114 void set*(***); 115 public <init>(android.content.Context); 116 public <init>(android.content.Context, android.util.AttributeSet); 117 public <init>(android.content.Context, android.util.AttributeSet, int); 118 } 119 -keep class com.example.odm.garbagesorthelper.widget.** { *; } 120 # 121 #----------------------------- WebView(專案中沒有可以忽略) ----------------------------- 122 # 123 #webView需要進行特殊處理 124 #在app中與HTML5的JavaScript的互動進行特殊處理 125 #我們需要確保這些js要呼叫的原生方法不能夠被混淆,於是我們需要做如下處理: 126 # 127 #---------------------------------實體類--------------------------- 128 #--------(實體Model不能混淆,否則找不到對應的屬性獲取不到值)----- 129 # 130 -keep class com.example.odm.garbagesorthelper.model.entity.** { *; } 131 -dontwarn com.example.odm.garbagesorthelper.model.entity.** 132 #對含有反射類的處理 133 -keep class com.example.odm.garbagesorthelper.utils.** { *; } 134 # 135 # ----------------------------- 其他的 ----------------------------- 136 # 137 # 刪除程式碼中Log相關的程式碼 138 -assumenosideeffects class android.util.Log { 139 public static boolean isLoggable(java.lang.String, int); 140 public static int v(...); 141 public static int i(...); 142 public static int w(...); 143 public static int d(...); 144 public static int e(...); 145 } 146 # 保持測試相關的程式碼 147 -dontnote junit.framework.** 148 -dontnote junit.runner.** 149 -dontwarn android.test.** 150 -dontwarn android.support.test.** 151 -dontwarn org.junit.** 152 # 153 # ----------------------------- 第三方庫、框架、SDK ----------------------------- 154 #logger 155 -dontwarn com.orhanobut.logger.** 156 -keep class com.orhanobut.logger.**{*;} 157 -keep interface com.orhanobut.logger.**{*;} 158 # Gson 159 -keep class com.google.gson.stream.** { *; } 160 -keepattributes EnclosingMethod 161 -dontwarn com.google.gson.** 162 -keep class com.google.gson.**{*;} 163 -keep interface com.google.gson.**{*;} 164 #gson 165 #如果用到Gson解析包的,直接新增下面這幾行就能成功混淆,不然會報錯。 166 ##---------------Begin: proguard configuration for Gson ---------- 167 # Gson uses generic type information stored in a class file when working with fields. Proguard 168 # removes such information by default, so configure it to keep all of it. 169 -keepattributes Signature 170 # For using GSON @Expose annotation 171 -keepattributes *Annotation* 172 # Gson specific classes 173 -dontwarn sun.misc.** 174 #-keep class com.google.gson.stream.** { *; } 175 # Prevent proguard from stripping interface information from TypeAdapterFactory, 176 # JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) 177 -keep class * implements com.google.gson.TypeAdapterFactory 178 -keep class * implements com.google.gson.JsonSerializer 179 -keep class * implements com.google.gson.JsonDeserializer 180 # Application classes that will be serialized/deserialized over Gso 181 # OkHttp3 182 -dontwarn okhttp3.logging.** 183 -keep class okhttp3.internal.**{*;} 184 -dontwarn okio.** 185 # Retrofit 186 -dontwarn retrofit2.** 187 -keep class retrofit2.** { *; } 188 #-keepattributes Signature-keepattributes Exceptions 189 # Platform calls Class.forName on types which do not exist on Android to determine platform. 190 -dontnote retrofit2.Platform 191 # Platform used when running on Java 8 VMs. Will not be used at runtime. 192 -dontwarn retrofit2.Platform$Java8 193 # Retain generic type information for use by reflection by converters and adapters. 194 -keepattributes Signature 195 # Retain declared checked exceptions for use by a Proxy instance. 196 -keepattributes Exceptions 197 # RxJava RxAndroid 198 -dontwarn sun.misc.** 199 -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { 200 long producerIndex; 201 long consumerIndex; 202 } 203 -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { 204 rx.internal.util.atomic.LinkedQueueNode producerNode; 205 } 206 -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { 207 rx.internal.util.atomic.LinkedQueueNode consumerNode; 208 } 209 #LiveEventBus 210 -dontwarn com.jeremyliao.liveeventbus.** 211 -keep class com.jeremyliao.liveeventbus.** { *; } 212 -keep class androidx.lifecycle.** { *; } 213 -keep class androidx.arch.core.** { *; } 214 #glide 215 -keep public class * implements com.bumptech.glide.module.GlideModule 216 -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { 217 **[] $VALUES; 218 public *; 219 } 220 #utilcodex 221 -keep class com.blankj.utilcode.util.** { *; } 222 # 223 -keep class site.gemus.** { *; } 224 #XUI 225 -keep class com.xuexiang.xui.** { *; } 226 #訊飛SDK 227 -libraryjars libs/Msc.jar 228 -libraryjars src/main/jniLibs/Msc.jar 229 -keep class com.iflytek.**{*;} 230 -keepattributes Signature 231 #RxPermission 232 -keep class com.tbruyelle.rxpermissions2.** { *; } 233 #XBanner 234 -keep class com.stx.xhb.androidx.XBanner.** { *; } 235 #Bugly SDK 236 -dontwarn com.tencent.bugly.** 237 -keep public class com.tencent.bugly.**{*;} 238 -keep class android.support.**{*;}