混淆規(guī)則
因?yàn)锳ndroid是使用Java開(kāi)發(fā)的,所以開(kāi)發(fā)者可以使用ProGuard對(duì)代碼進(jìn)行混淆。SDK已經(jīng)集成了ProGuard工具,開(kāi)發(fā)者可以從SDK目錄下的\tools\proguard目錄中進(jìn)行查看。
ProGuard是一個(gè)免費(fèi)的**Java****類(lèi)文件收縮,優(yōu)化,混淆和預(yù)校驗(yàn)器。它可以檢測(cè)并刪除未使用的類(lèi),字段,方法和屬性。它可以優(yōu)化字節(jié)碼,并刪除未使用的指令。它可以將類(lèi)、字段和方法使用短無(wú)意義的名稱(chēng)進(jìn)行重命名**。最后,預(yù)校驗(yàn)的Java6或針對(duì)Java MicroEdition的所述處理后的碼。
下面就和大家分享一下對(duì)使用了第三方庫(kù)的項(xiàng)目進(jìn)行混淆的經(jīng)驗(yàn)。
ProGuard默認(rèn)會(huì)對(duì)第三方庫(kù)也進(jìn)行混淆的,而第三方庫(kù)有的已經(jīng)混淆過(guò)了,有的使用了Java反射技術(shù),所以我們?cè)谶M(jìn)行代碼混淆的時(shí)候要排除這些第三方庫(kù)。排除對(duì)第三方庫(kù)的混淆需要在混淆規(guī)則文件(通常是:proguard-project.txt或proguard.cfg或proguard-rules.pro或proguard-rules.txt也可以是其它的文件名只要在配置文件中將含有混淆規(guī)則的文件名配置進(jìn)去就行了)中添加如下規(guī)則:
1.如果使用了Gson之類(lèi)的工具要使JavaBean類(lèi)即實(shí)體類(lèi)不被混淆。
2.如果使用了自定義控件那么要保證它們不參與混淆。
3.如果使用了枚舉要保證枚舉不被混淆。
4.對(duì)第三方庫(kù)中的類(lèi)不進(jìn)行混淆
a.混淆時(shí)保護(hù)引用的第三方j(luò)ar包
如:-libraryjars libs/baidumapapi_v3_2_0.jar #保護(hù)引用的第三方j(luò)ar包不被混淆
注意:在使用Eclipse+ADT時(shí)需要加入-libraryjars libs/...,如果你是使用Android Studio開(kāi)發(fā)的項(xiàng)目則不需要加入libs包中的jar包,這是因?yàn)椋ㄟ^(guò)Android Studio進(jìn)行混淆代碼時(shí),默認(rèn)已經(jīng)將 lib目錄中的 jar 都已經(jīng)添加到打包腳本中,所以不需要再次手動(dòng)添加,否則會(huì)出現(xiàn)“ java.io.IOException: The same input jar is specified twice” 錯(cuò)誤。
b.混淆時(shí)保護(hù)第三方j(luò)ar包中的類(lèi)不被混淆
如:-keep class com.baidu.** { ; } #讓ProGuard不要警告找不到com.baidu.*這個(gè)包里面的類(lèi)的相關(guān)引用
-dontwarn com.baidu.** #保持com.baidu.**這個(gè)包里面的所有類(lèi)和所有方法不被混淆。
附:小編開(kāi)發(fā)中用到的一些混淆規(guī)則,大家可以根據(jù)需要復(fù)制到自己的項(xiàng)目中的混淆規(guī)則的文件中即可。
[plain] view plain copy [圖片上傳失敗...(image-96b93b-1530078982655)] [圖片上傳失敗...(image-e32e22-1530078982651)]
################common###############
-keep class com.jph.android.entity.** { *; } #實(shí)體類(lèi)不參與混淆
-keep class com.jph.android.view.** { *; } #自定義控件不參與混淆
################baidu map###############
-libraryjars libs/baidumapapi_v3_2_0.jar
-libraryjars libs/locSDK_5.0.jar
-keep class com.baidu.** { *; }
-keep class vi.com.gdi.bgl.android.*{;}
-dontwarn com.baidu.**
################afinal##################
-
-libraryjars libs/afinal_0.5_bin.jar
-
-keep class net.tsz.afinal.** { *; }
-
-keep public class * extends net.tsz.afinal.**
-
-keep public interface net.tsz.afinal.** {*;}
-
-dontwarn net.tsz.afinal.**
################xutils##################
-libraryjars libs/xUtils-2.6.14.jar
-keep class com.lidroid.xutils.** { *; }
-keep public class * extends com.lidroid.xutils.**
-keepattributes Signature
-keepattributes Annotation
-keep public interface com.lidroid.xutils.** {*;}
-dontwarn com.lidroid.xutils.**
-keepclasseswithmembers class com.jph.android.entity.** {
<fields>;
<methods>;
}
################支付寶##################
-libraryjars libs/alipaysecsdk.jar
-libraryjars libs/alipayutdid.jar
-libraryjars libs/alipaysdk.jar
-keep class com.alipay.android.app.IAliPay{*;}
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.lib.ResourceMap{*;}
################gson##################
-libraryjars libs/gson-2.2.4.jar
-keep class com.google.gson.** {*;}
-
-keep class com.google.*{;}
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.google.** {
<fields>;
<methods>;
}
-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();
}
-dontwarn com.google.gson.**
################httpmime/httpcore##########
-libraryjars libs/httpcore-4.3.2.jar
-libraryjars libs/httpmime-4.3.5.jar
-keep class org.apache.http.** {*;}
-dontwarn org.apache.http.**
####################jpush##################
-libraryjars libs/jpush-sdk-release1.7.1.jar
-keep class cn.jpush.** { *; }
-keep public class com.umeng.fb.ui.ThreadView { } #雙向反饋功能代碼不混淆
-dontwarn cn.jpush.**
-keepclassmembers class * {
public <init>(org.json.JSONObject);
}
-
不混淆R類(lèi)
-keep public class com.jph.android.R$*{
public static final int *;
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
####################umeng##################
-libraryjars libs/umeng-analytics-v5.2.4.jar
-keep class com.umeng.analytics.** {*;}
-dontwarn com.umeng.analytics.**
-
-keep public class * extends com.umeng.**
-
-keep public class * extends com.umeng.analytics.**
-
-keep public class * extends com.umeng.common.**
-
-keep public class * extends com.umeng.newxp.**
-keep class com.umeng.** { *; }
-keep class com.umeng.analytics.** { *; }
-keep class com.umeng.common.** { *; }
-keep class com.umeng.newxp.** { *; }
-keepclassmembers class * {
public <init>(org.json.JSONObject);
}
-keep class com.umeng.**
-keep public class com.idea.fifaalarmclock.app.R$*{
public static final int *;
}
-keep public class com.umeng.fb.ui.ThreadView {
}
-dontwarn com.umeng.**
-dontwarn org.apache.commons.**
-keep public class * extends com.umeng.**
-keep class com.umeng.** {*; }
####################universal-image-loader########
-libraryjars libs/universal-image-loader-1.9.3.jar
-keep class com.nostra13.universalimageloader.** {*;}
-dontwarn com.nostra13.universalimageloader.**
####################zxing#####################
-libraryjars libs/zxing.jar
-libraryjars libs/zxing_apply.jar
-keep class com.google.zxing.** {*;}
-dontwarn com.google.zxing.**
####################BASE64Decoder##################
-libraryjars libs/sun.misc.BASE64Decoder.jar
####################support.v4#####################
-libraryjars libs/android-support-v4.jar
-keep class android.support.v4.** { *; }
-dontwarn android.support.v4.**
###################other####################
-
slidingmenu 的混淆
-dontwarn com.jeremyfeinstein.slidingmenu.lib.**
-keep class com.jeremyfeinstein.slidingmenu.lib.** { *; }
-
ActionBarSherlock混淆
-dontwarn com.actionbarsherlock.**
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
-keep class * extends java.lang.annotation.Annotation { *; }
-keepclasseswithmembernames class * {
native <methods>;
}
-keep class com.jph.android.entity.** {
<fields>;
<methods>;
}
-dontwarn android.support.**
-dontwarn com.slidingmenu.lib.app.SlidingMapActivity
-keep class android.support.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
-keep class com.slidingmenu.** { *; }
-keep interface com.slidingmenu.** { *; }
推薦閱讀:《Android****開(kāi)發(fā)之反編譯與防止反編譯》
proguard.cfg配置文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
#``指定代碼的壓縮級(jí)別
-optimizationpasses
5
#``包明不混合大小寫(xiě)
-dontusemixedcaseclassnames
#``不去忽略非公共的庫(kù)類(lèi)
-dontskipnonpubliclibraryclasses
#``優(yōu)化 不優(yōu)化輸入的類(lèi)文件
-dontoptimize
#``預(yù)校驗(yàn)
-dontpreverify
#``混淆時(shí)是否記錄日志
-verbose
#
混淆時(shí)所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!**class**/merging/*
#``保護(hù)注解
-keepattributes *Annotation*
#
保持哪些類(lèi)不被混淆
-keep
**public class**``*
**extends **``android.app.Fragment
-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**``com.android.vending.licensing.ILicensingService
#``如果有引用v4包可以添加下面這行
-keep
**public class**``*
**extends **``android.support.v4.app.Fragment
#``忽略警告
-ignorewarning
#####################``記錄生成的日志數(shù)據(jù),gradle build時(shí)在本項(xiàng)目根目錄輸出################
#apk
包內(nèi)所有
**class**``的內(nèi)部結(jié)構(gòu)
-dumpclass_files.txt
#``未混淆的類(lèi)和成員
-printseeds seeds.txt
#``列出從 apk 中刪除的代碼
-printusage unused.txt
#``混淆前后的映射
-printmapping mapping.txt
#####################``記錄生成的日志數(shù)據(jù),gradle build時(shí) 在本項(xiàng)目根目錄輸出-end################
################<span></span>``混淆保護(hù)自己項(xiàng)目的部分代碼以及引用的第三方j(luò)ar包library#########################
#-libraryjars libs/umeng-analytics-v5.2.4.jar
#-libraryjars libs/alipaysd<span></span>k.jar
#<span></span>-libraryjars libs/alipaysecsdk.jar
#-libraryjars libs/alipayutdid.jar
#-libraryjars libs/wup-1.0.0-SNAPSHOT.jar
#-libraryjars libs/weibosdkcore.jar
#``三星應(yīng)用市場(chǎng)需要添加:sdk-v1.0.0.jar,look-v1.0.1.jar
#-libraryjars libs/sdk-v1.0.0.jar
#-libraryjars libs/look-v1.0.1.jar
#``我是以libaray的形式引用了一個(gè)圖片加載框架,如果不想混淆 keep 掉
-keep
**class**``com.nostra13.universalimageloader.** { *; }
#``友盟
-keep
**class**``com.umeng.**{*;}
#``支付寶
-keep
**class**``com.alipay.android.app.IAliPay{*;}
-keep
**class**``com.alipay.android.app.IAlixPay{*;}
-keep
**class**``com.alipay.android.app.IRemoteServiceCallback{*;}
-keep
**class**``com.alipay.android.app.lib.ResourceMap{*;}
#``信鴿推送
-keep
**class**``com.tencent.android.tpush.** {* ;}
-keep
**class**``com.tencent.mid.** {* ;}
#``自己項(xiàng)目特殊處理代碼
#``忽略警告
-dontwarn com.veidy.mobile.common.**
#``保留一個(gè)完整的包
-keep
**class**``com.veidy.mobile.common.** {
*;
}
-keep
**class**
com.veidy.activity.login.WebLoginActivity{*;}
-keep
**class**
com.veidy.activity.UserInfoFragment{*;}
-keep
**class**
com.veidy.activity.HomeFragmentActivity{*;}
-keep
**class**
com.veidy.activity.CityActivity{*;}
-keep
**class**
com.veidy.activity.ClinikActivity{*;}
#``如果引用了v4或者v7包
-dontwarn android.support.**
############<span></span>``混淆保護(hù)自己項(xiàng)目的部分代碼以及引用的第三方j(luò)ar包library-end##################
-keep
**publicclass**``*
**extends**``android.view.View {
**public**``<init>(android.content.Context);
**public**``<init>(android.content.Context, android.util.AttributeSet);
**public**``<init>(android.content.Context, android.util.AttributeSet,
int);
**public**``voidset*(...);
}
#``保持 native 方法不被混淆
-keepclasseswithmembernames
**class**``* {
native <methods>;
}
#``保持自定義控件類(lèi)不被混淆
-keepclasseswithmembers
**class**``* {
**public**``<init>(android.content.Context, android.util.AttributeSet);
}
#``保持自定義控件類(lèi)不被混淆
-keepclasseswithmembers
**class**``* {
**public**``<init>(android.content.Context, android.util.AttributeSet,
int);
}
#``保持自定義控件類(lèi)不被混淆
-keepclassmembers
**class**``*
**extends**``android.app.Activity {
**public**``void*(android.view.View);
}
#``保持 Parcelable 不被混淆
-keep
**class**``*
**implements**``android.os.Parcelable {
**publicstatic**``final android.os.Parcelable$Creator *;
}
#``保持 Serializable 不被混淆
-keepnames
**class**``*
**implements**``java.io.Serializable
#``保持 Serializable 不被混淆并且enum 類(lèi)也不被混淆
-keepclassmembers
**class**``*
**implements**``java.io.Serializable {
**static**``final
longserialVersionUID;
**privatestatic**``final java.io.ObjectStreamField[] serialPersistentFields;
!**static**!transient <fields>;
!**private**<fields><span></span>;
!**private**<methods>;
**private**``voidwriteObject(java.io.ObjectOutputStream);
**private**``voidreadObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
#``保持枚舉 enum 類(lèi)不被混淆 如果混淆報(bào)錯(cuò),建議直接使用上面的 -keepclassmembers**class***
**implements**``java.io.Serializable``即可
#-keepclassmembers enum * {
#
**publicstatic**``**[] values();
#
**publicstatic**``** valueOf(java.lang.String);
#}
-keepclassmembers
**class**``* {
**public**``void*ButtonClicked(android.view.View);
}
#``不混淆資源類(lèi)
-keepclassmembers
**class**``**.R$* {
**publicstatic**``<fields>;
}
#``避免混淆泛型 如果混淆報(bào)錯(cuò)建議關(guān)掉
#–keepattributes Signature
#``移除log 測(cè)試了下沒(méi)有用還是建議自己定義一個(gè)開(kāi)關(guān)控制是否輸出日志
#-assumenosideeffects
**class**``android.util.Log {
#
**publicstatic**``booleanisLoggable(java.lang.String,
int);
#
**publicstatic**``intv(...);
#
**publicstatic**``inti(...);
#
**publicstatic**``intw(...);
#
**publicstatic**``intd(...);
#
**publicstatic**``inte(...);
#}
|
另外加上一段,如果用用到Gson解析包的,直接添加下面這幾行就能成功混淆,不然會(huì)報(bào)錯(cuò)。
|
1
2
3
4
5
6
7
|
#gson
#-libraryjars libs/gson-2.2.2.jar
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
|
如果你使用了webview
|
1
2
3
4
5
6
7
8
9
10
|
# webview + js
-keepattributes *JavascriptInterface*
# keep
使用 webview 的類(lèi)
-keepclassmembers
**class**
com.veidy.activity.WebViewActivity {
**public**``*;
}
# keep
使用 webview 的類(lèi)的所有的內(nèi)部類(lèi)
-keepclassmembers
**class**
com.veidy.activity.WebViewActivity$*{
*;
}
|
混淆后生成apk文件比混淆前生成的apk文件要小不少