詳解Android代碼混淆實(shí)戰(zhàn)
什么是代碼混淆:
Android SDK 自帶了混淆工具Proguard。它位于SDK根目錄\tools\proguard下面。如果開(kāi)啟了混淆,Proguard默認(rèn)情況下會(huì)對(duì)所有代碼,包括第三方包都進(jìn)行混淆,可是有些代碼或者第三方包是不能混淆的,這就需要我們手動(dòng)編寫(xiě)混淆規(guī)則來(lái)保持不能被混淆的部分。
為什么要混淆:
- 優(yōu)化java的字節(jié)碼
- 減小apk文件的大小,在混淆過(guò)程中會(huì)刪除未使用過(guò)的類(lèi)和成員
- 代碼安全,使類(lèi)、函數(shù)、變量名隨機(jī)變成無(wú)意義的代號(hào)形如:a,b,c...之類(lèi)。防止app被反編譯之后能夠很容易的看懂代碼
怎樣使用混淆
在app下面的build.gradle添加使用混淆
buildTypes {
release {
//開(kāi)啟混淆,刪除無(wú)用代碼
minifyEnabled true
//開(kāi)啟刪除無(wú)用資源
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
//在debug環(huán)境下使用混淆,方便調(diào)試
signingConfig signingConfigs.debug
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
manifestPlaceholders = [
// UAT 測(cè)試環(huán)境
GETUI_APP_ID : "FZi793fjp9654LfeDPcR29",
GETUI_APP_KEY : "YrVmZT4KTp65hqAtZbCj79",
GETUI_APP_SECRET: "aLf186Rb617uj7jeNnUB89"
]
}
}
}
debug環(huán)境下使用簽名文件,方便在debug環(huán)境下調(diào)試混淆后的代碼
混淆文件 proguard-rules.pro
通用混淆配置(APP通用)
##################################通過(guò)混淆配置################################# # 代碼混淆壓縮比,在0~7之間,默認(rèn)為5,一般不做修改 -optimizationpasses 5 # 混合時(shí)不使用大小寫(xiě)混合,混合后的類(lèi)名為小寫(xiě) -dontusemixedcaseclassnames # 指定不去忽略非公共庫(kù)的類(lèi) -dontskipnonpubliclibraryclasses # 這句話能夠使我們的項(xiàng)目混淆后產(chǎn)生映射文件 # 包含有類(lèi)名->混淆后類(lèi)名的映射關(guān)系 -verbose # 指定不去忽略非公共庫(kù)的類(lèi)成員 -dontskipnonpubliclibraryclassmembers # 不做預(yù)校驗(yàn),preverify是proguard的四個(gè)步驟之一,Android不需要preverify,去掉這一步能夠加快混淆速度。 -dontpreverify -dontoptimize # 混淆時(shí)是否記錄日志 -verbose -ignorewarnings # 保留Annotation不混淆 -keepattributes *Annotation* # 避免混淆泛型 -keepattributes Signature -keepattributes Exceptions,InnerClasses -dontnote com.google.vending.licensing.ILicensingService -dontnote com.android.vending.licensing.ILicensingService # 拋出異常時(shí)保留代碼行號(hào) -keepattributes SourceFile,LineNumberTable -keepattributes Deprecated,Synthetic,EnclosingMethod # 重命名拋出異常時(shí)的文件名稱 -renamesourcefileattribute SourceFile # 指定混淆是采用的算法,后面的參數(shù)是一個(gè)過(guò)濾器 # 這個(gè)過(guò)濾器是谷歌推薦的算法,一般不做更改 -optimizations !code/simplification/cast,!field/*,!class/merging/*
APP需要保留的公共部分(通用)
- 四大組件以及子類(lèi);
- 自定義Application;
- support下面的繼承子類(lèi)
- R下面的資源
- native方法
- Activity中參數(shù)是view的方法
- 枚舉
- 自定義View
- 序列化(Parcelable,Serializable)
- 帶有回調(diào)函數(shù)(On* Listener,On Event)
- WebView
#############################################
#
# Android開(kāi)發(fā)中一些需要保留的公共部分
#
#############################################
# 保留我們使用的四大組件,自定義的Application等等這些類(lèi)不被混淆
# 因?yàn)檫@些子類(lèi)都有可能被外部調(diào)用
-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
# 保留support下的所有類(lèi)及其內(nèi)部類(lèi)
-keep class android.support.** {*;}
# 保留繼承的
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
# 保留R下面的資源
-keep class **.R$* {*;}
# 保留本地native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
# 保留在Activity中的方法參數(shù)是view的方法,
# 這樣以來(lái)我們?cè)趌ayout中寫(xiě)的onClick就不會(huì)被影響
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
# 保留枚舉類(lèi)不被混淆
-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序列化類(lèi)不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# 保留Serializable序列化的類(lèi)不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# 對(duì)于帶有回調(diào)函數(shù)的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
}
# webView處理,項(xiàng)目中沒(méi)有使用到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);
保留自己的項(xiàng)目部分代碼不能被混淆(需要更具自己項(xiàng)目)
- 網(wǎng)絡(luò)請(qǐng)求(如果混淆,就會(huì)發(fā)生字段的錯(cuò)亂,無(wú)法正常解析)
- 加密類(lèi)
- 數(shù)據(jù)庫(kù)實(shí)體類(lèi)
- 工具類(lèi)
- 項(xiàng)目中應(yīng)用到的第三方工具類(lèi)(如okhttp,eventbus,rxjava等),需要根據(jù)具體的工具介紹進(jìn)行操作
- 保留lib和compile引用的第三方j(luò)ar包不被混淆的方法:
java -keep class 包名.** { *; } 。
如:保留引用的科大訊飛的第三方j(luò)ar包不被混淆
java -keep class com.iflytek.** { *; }
#網(wǎng)絡(luò)請(qǐng)求等與外界通信不能混淆
-keep class com.xxxxx.function.**.net.** { *; }
-keep class com.xxxxx.function.**.bean.** { *; }
-keep class com.xxxxx.common.net.** { *; }
-keep class com.xxxxx.common.bean.** { *; }
#加密不能混淆
-keep class com.xxxxx.crypt.** {*;}
#數(shù)據(jù)庫(kù)實(shí)體類(lèi)不能混淆
-keep class com.xxxxxx.function.**.dao.** { *; }
#工具類(lèi)不混淆
-keep class com.xxxxx.common.utils.** { *; }
#greenDAO 3
#-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
#public static java.lang.String TABLENAME;
#}
#-keep class **$Properties
#-dontwarn org.greenrobot.greendao.database.**
#-dontwarn rx.**
#greenDAO 3
# Fresco
#-keep class com.facebook.** {*;}
#-keep interface com.facebook.** {*;}
#-keep enum com.facebook.** {*;}
# OkHttp3
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
#Picasso
#-dontwarn com.squareup.okhttp.**
#zxing
-dontwarn com.google.zxing.**
-keep class com.google.zxing.** { *; }
#webview
-dontwarn com.tencent.**
#eventbus不能混淆
-keepattributes *Annotation*
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
#如果項(xiàng)目中倒入了de.greenrobot.even的beta1版本,需要添加此行代碼
-keepclassmembers class ** {
public void onEvent*(**);
}
#高德
-dontwarn com.amap.api.**
-keep class com.amap.api.** {*;}
#bugout
-dontwarn com.qamaster.android.**
-dontwarn com.testin.agent.**
-keepattributes InnerClasses
-keep class com.testin.agent.** { *; }
-keepattributes SourceFile, LineNumberTable
#butterknife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
#sharesdk
-keep class cn.sharesdk.**{*;}
-keep class com.sina.**{*;}
-keep class **.R$* {*;}
-keep class **.R{*;}
-dontwarn cn.sharesdk.**
-dontwarn **.R$*
-dontwarn com.tencent.**
-keep class com.tencent.** {*;}
# rx
-dontwarn rx.**
-keepclassmembers class rx.** { *; }
# retrolambda
-dontwarn java.lang.invoke.*
# Glide specific rules #
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
#友盟統(tǒng)計(jì)
-keep class com.umeng.message.protobuffer.* {
public <fields>;
public <methods>;
}
-keep class com.umeng.message.* {
public <fields>;
public <methods>;
}
#ormLite
-keep public class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
-keep public class * extends com.j256.ormlite.android.apptools.OpenHelperManager
-keepclassmembers class * {@com.j256.ormlite.field.DatabaseField *;}
-keep class com.j256.ormlite.** {*;}
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
#zbar
-keep class net.sourceforge.zbar.**{*;}
-keep class com.nineoldandroids.** {*;}
#身份證ocr
-keep class com.yd.ocr.idcard.** { *; }
-keep class com.googlecode.** { *; }
-keep class org.opencv.** { *; }
#訊飛語(yǔ)音
-keep class com.iflytek.** { *; }
# FastJson 混淆代碼
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keepattributes Signature
-keepattributes *Annotation*
至此,代碼混淆已經(jīng)介紹完畢,有問(wèn)題請(qǐng)及時(shí)指出,一起學(xué)習(xí),謝謝。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用插件實(shí)現(xiàn)代碼混淆
- Android 一些常用的混淆Proguard
- Android Studio配置反混淆的實(shí)現(xiàn)
- Android studio 混淆配置詳解
- Android常用三方庫(kù)混淆規(guī)則整理(小結(jié))
- Android代碼混淆的寫(xiě)法總結(jié)
- proguar在Android混淆中的用法
- 詳解Android的反編譯和代碼混淆
- Android studio 混淆+打包+驗(yàn)證是否成功
- Android studio利用gradle打jar包并混淆的方法詳解
- Android 資源混淆的方案及注意事項(xiàng)
相關(guān)文章
flutter實(shí)現(xiàn)更新彈窗內(nèi)容例子(親測(cè)有效)
Flutter是一款移動(dòng)應(yīng)用程序SDK,包含框架、widget和工具,這篇文章給大家介紹flutter實(shí)現(xiàn)更新彈窗內(nèi)容例子,親測(cè)可以使用,需要的朋友參考下吧2021-04-04
android實(shí)現(xiàn)來(lái)電靜音示例(監(jiān)聽(tīng)來(lái)電)
這篇文章主要介紹了手機(jī)來(lái)電鈴聲響起后,通過(guò)此代碼實(shí)現(xiàn)靜音而非掛斷的方法的相關(guān)資料2014-03-03
Android 有道詞典的簡(jiǎn)單實(shí)現(xiàn)方法介紹
本篇文章小編為大家介紹,Android 有道詞典的簡(jiǎn)單實(shí)現(xiàn)方法介紹。需要的朋友參考下2013-04-04
Android TextView和ImageView簡(jiǎn)單說(shuō)明
Android TextView和ImageView簡(jiǎn)單說(shuō)明,需要的朋友可以參考一下2013-03-03
解決Android軟鍵盤(pán)彈出覆蓋h5頁(yè)面輸入框問(wèn)題
之前我們?cè)谑褂胿ue進(jìn)行 h5 表單錄入的過(guò)程中,遇到了Android軟鍵盤(pán)彈出,覆蓋 h5頁(yè)面 輸入框 問(wèn)題,在此進(jìn)行回顧并分享給大家,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05
android RecycleView實(shí)現(xiàn)多級(jí)樹(shù)形列表
這篇文章主要為大家詳細(xì)介紹了android RecycleView實(shí)現(xiàn)多級(jí)樹(shù)形列表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
android Watchdog 實(shí)現(xiàn)剖析
Android提供了Watchdog類(lèi),用來(lái)監(jiān)測(cè)Service是否處于正常工作中,是在SystemServer中啟動(dòng)的;本文將詳細(xì)介紹2012-11-11

