├── LICENSE ├── README.md └── proguard-rules.pro /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AndroidProguard 2 | Android代码混淆,包含了通用混淆配置,以及常用的第三方库混淆配置 3 | 4 | # 简介 5 | 6 | 作为Android开发者,如果你不想开源你的应用,那么在应用发布前,就需要对代码进行混淆处理,从而让我们代码即使被反编译,也难以阅读。混淆概念虽然容易,但很多初学者也只是网上搜一些成型的混淆规则粘贴进自己项目,并没有对混淆有个深入的理解。本篇文章的目的就是让一个初学者在看完后,能在不进行任何帮助的情况下,独立写出适合自己代码的混淆规则。 7 | 8 | 代码压缩通过 ProGuard 提供,ProGuard 会检测和移除封装应用中未使用的类、字段、方法和属性,包括自带代码库中的未使用项(这使其成为以变通方式解决 64k 引用限制的有用工具)。ProGuard 还可优化字节码,移除未使用的代码指令,以及用短名称混淆其余的类、字段和方法。混淆过的代码可令您的 APK 难以被逆向工程,这在应用使用许可验证等安全敏感性功能时特别有用。 9 | 10 | ## 混淆介绍 11 | 12 | Android中的“混淆”可以分为两部分,一部分是 Java 代码的优化与混淆,依靠 proguard 混淆器来实现;另一部分是资源压缩,将移除项目及依赖的库中未被使用的资源(资源压缩严格意义上跟混淆没啥关系)。 13 | 14 | 我们通常说的proguard(代码混淆)包括以下四个方面: 15 | 1. shrink(压缩): 检测并移除没有用到的类,变量,方法和属性; 16 | 2. optimize(优化): 分析和优化代码,优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行; 17 | 3. obfuscate(混淆): 把类名、属性名、方法名替换为简短且无意义的名称,增大反编译难度; 18 | 4. preverify(预校验): 预校验是作用在Java平台上的(校验代码是否符合Java1.6+),Android平台上不需要这项功能,去掉之后还可以加快混淆速度。 19 | 20 | 这四个流程默认开启,在 Android 项目中我们可以选择将“优化”和“预校验”关闭,对应命令是-dontoptimize、-dontpreverify 21 | 22 | 23 | 24 | ## 代码混淆 25 | 26 | Android Studio集成了Java语言的ProGuard作为压缩,优化和混淆的工具,使用起来很方便。 27 | 首先要通过ProGuard启用代码混淆,首先要在app module下的build.gradle文件将“minifyEnabled”属性设置为true,以便开启代码混淆(开启混淆会使编译时间变长,默认关闭): 28 | ``` java 29 | android { 30 | buildTypes { 31 | release { 32 | minifyEnabled true // 代码混淆(true为打开,开启混淆会使编译时间变长,默认不开启) 33 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 34 | } 35 | } 36 | } 37 | ``` 38 | 39 | 在上面的“混淆配置”中有这样一行代码 40 | ``` 41 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 42 | ``` 43 | proguard-android.txt,这是系统默认的混淆文件,具体在../sdk/tools/proguard/ 目录下,其中包含了android最基本的混淆,一般不需要改动; 44 | 我们需要配置的是项目中app下的 proguard-rules.pro 文件 45 | 46 | 47 | ProGuard作用 48 | 49 | -dontshrink 关闭压缩 50 | -optimizationpasses n 表示proguard对代码进行迭代优化的次数,Android一般为5 51 | -dontobfuscate 关闭混淆 52 | 53 | 混淆后默认会在工程目录app/build/outputs/mapping/release下生成一个mapping.txt文件,这就是混淆规则,我们可以根据这个文件把混淆后的代码反推回源本的代码,所以这个文件很重要,注意保护好。原则上,代码混淆后越乱越无规律越好,但有些地方我们是要避免混淆的,否则程序运行就会出错,所以就有了下面我们要教大家的,如何让自己的部分代码避免混淆从而防止出错。 54 | 55 | 56 | ## 混淆规则 57 | 58 | 1.基本规则 59 | 60 | 1. 常见混淆命令: 61 | 62 | 命令 作用 63 | -keep 防止类和成员被移除或者被重命名 64 | -keepnames 防止类和成员被重命名 65 | -keepclassmembers 防止成员被移除或者被重命名 66 | -keepclasseswithmembers 防止拥有该成员的类和成员被移除或者被重命名 67 | -keepclasseswithmembernames 防止拥有该成员的类和成员被重命名 68 | 69 | 2. 保持元素不参与混淆的规则 70 | 71 | 语句结构:[保持命令] [类] { [成员] } 72 | 73 | “类”表示符合相关限定条件的类,它的内容可以使用: 74 | - 具体的类 75 | - 访问修饰符(public、protected、private) 76 | - 通配符*,匹配任意长度字符,但不含包名分隔符(.) 77 | - 通配符**,匹配任意长度字符,并且包含包名分隔符(.) 78 | - extends,即可以指定类的基类 79 | - implement,匹配实现了某接口的类 80 | - $,内部类 81 | 82 | “成员”表示符合相关限定条件的类成员,它的内容可以使用: 83 | - 匹配所有构造器 84 | - 匹配所有域 85 | - 匹配所有方法 86 | - 通配符*,匹配任意长度字符,但不含包名分隔符(.) 87 | - 通配符**,匹配任意长度字符,并且包含包名分隔符(.) 88 | - 通配符***,匹配任意参数类型 89 | - …,匹配任意长度的任意类型参数。比如void test(…)就能匹配任意 void test(String a) 或者是 void test(int a, String b) 这些方法。 90 | - 访问修饰符(public、protected、private) 91 | 92 | 举个例子,假如需要将name.huihui.test包下所有继承Activity的public类及其构造函数都保持住,可以这样写: 93 | -keep public class name.huihui.test.** extends Android.app.Activity { 94 | 95 | } 96 | 3. 常用的自定义混淆规则 97 | 98 | 不混淆某个类 99 | -keep public class name.huihui.example.Test { *; } 100 | 101 | 不混淆某个包所有的类 102 | -keep class name.huihui.test.** { *; } 103 | 104 | 不混淆某个类的子类 105 | -keep public class * extends name.huihui.example.Test { *; } 106 | 107 | 不混淆所有类名中包含了“model”的类及其成员 108 | -keep public class **.*model*.** {*;} 109 | 110 | 不混淆某个接口的实现 111 | -keep class * implements name.huihui.example.TestInterface { *; } 112 | 113 | 不混淆某个类的构造方法 114 | -keepclassmembers class name.huihui.example.Test { 115 | public (); 116 | } 117 | 118 | 不混淆某个类的特定的方法 119 | -keepclassmembers class name.huihui.example.Test { 120 | public void test(java.lang.String); 121 | } 122 | 123 | 124 | 再者,如果一个类中你不希望保持全部内容不被混淆,而只是希望保护类下的特定内容,就可以使用 125 | 126 | ; //匹配所有构造器 127 | ; //匹配所有域 128 | ; //匹配所有方法方法 129 | 你还可以在前面加上private 、public、native等来进一步指定不被混淆的内容,如 130 | 131 | -keep class cn.hadcn.test.One { 132 | public ; 133 | } 134 | 表示One类下的所有public方法都不会被混淆,当然你还可以加入参数,比如以下表示用JSONObject作为入参的构造函数不会被混淆 135 | 136 | -keep class cn.hadcn.test.One { 137 | public (org.json.JSONObject); 138 | } 139 | 有时候你是不是还想着,我不需要保持类名,我只需要把该类下的特定方法保持不被混淆就好,那你就不能用keep方法了,keep方法会保持类名,而需要用keepclassmembers ,如此类名就不会被保持,为了便于对这些规则进行理解,官网给出了以下表格 140 | 141 | 保留 防止被移除或者被重命名 防止被重命名 142 | 类和类成员 -keep -keepnames 143 | 仅类成员 -keepclassmembers -keepclassmembernames 144 | 如果拥有某成员,保留类和类成员 -keepclasseswithmembers -keepclasseswithmembernames 145 | 146 | ## 注意事项 147 | 1. jni方法不可混淆(jni方法必须要跟native方法一致); 148 | 2. 反射用到的类不混淆(否则反射可能出现问题); 149 | 4. 使用了 Gson 之类的工具要使 JavaBean 类即实体类不被混淆(否则无法将JSON解析成对应的对象); 150 | 5. 添加第三方库所需的混淆规则(一般都在文档中会写混淆规则,使用时注意添加) 151 | 6. 有用到WebView的JS调用也需要保证写的接口方法不混淆; 152 | 7. Parcelable的子类和Creator静态成员变量不混淆(否则会抛出BadParcelableException异常); 153 | 8. enum类型(枚举)不进行混淆 154 | 155 | - 所有在 AndroidManifest.xml 涉及到的类已经自动被保持,因此不用特意去添加这块混淆规则。(很多老的混淆文件里会加,现在已经没必要) 156 | - proguard-android.txt 已经存在一些默认混淆规则,没必要在 proguard-rules.pro 重复添加 157 | 158 | 关于第三方库的混淆规则,github上有相关的库[android-proguard-snippets](https://github.com/krschultz/android-proguard-snippets),但已经几年没更新了,所以还是希望自己手动添加 159 | 160 | 161 | 3. 检查混淆结果 162 | 163 | 混淆过的包必须进行检查,避免因混淆引入的bug。 164 | 165 | 一方面,需要从代码层面检查。使用上文的配置进行混淆打包后在 /build/outputs/mapping/release/ 目录下会输出以下文件: 166 | - dump.txt 167 | 描述APK文件中所有类的内部结构 168 | - mapping.txt 169 | 提供混淆前后类、方法、类成员等的对照表 170 | - seeds.txt 171 | 列出没有被混淆的类和成员 172 | - usage.txt 173 | 列出被移除的代码 174 | 175 | 我们可以根据 seeds.txt 文件检查未被混淆的类和成员中是否已包含所有期望保留的,再根据 usage.txt 文件查看是否有被误移除的代码。 176 | 177 | 另一方面,需要从测试方面检查。将混淆过的包进行全方面测试,检查是否有 bug 产生。 178 | 179 | 180 | 181 | 182 | 183 | ## 基本的混淆模板 184 | 这里提供一份基本的混淆模板,适用于大部分项目 185 | 当然第三方库,或者上面提到的地方,需要根据项目的实际需求进行混淆 186 | 187 | ``` 188 | ############################################# 189 | # 190 | # 基础混淆配置 191 | # 192 | ############################################# 193 | 194 | 195 | ####################基本混淆指令的设置#################### 196 | 197 | # 代码混淆压缩比,在0~7之间,默认为5,一般不做修改 198 | -optimizationpasses 5 199 | 200 | # 混合时不使用大小写混合,混合后的类名为小写 201 | -dontusemixedcaseclassnames 202 | 203 | # 优化时允许访问并修改有修饰符的类和类的成员 204 | -allowaccessmodification 205 | 206 | # 指定不忽略非公共库的类 207 | -dontskipnonpubliclibraryclasses 208 | 209 | # 指定不忽略非公共库的类成员 210 | -dontskipnonpubliclibraryclassmembers 211 | 212 | # 记录日志,使我们的项目混淆后产生映射文件(类名->混淆后类名) 213 | -verbose 214 | 215 | # 忽略警告,避免打包时某些警告出现,没有这个的话,构建报错 216 | -ignorewarnings 217 | 218 | # 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。 219 | -dontpreverify 220 | 221 | # 不混淆Annotation(保留注解) 222 | -keepattributes *Annotation*,InnerClasses 223 | 224 | # 避免混淆泛型 225 | -keepattributes Signature 226 | 227 | # 抛出异常时保留代码行号 228 | -keepattributes SourceFile,LineNumberTable 229 | 230 | # 指定混淆是采用的算法,后面的参数是一个过滤器 231 | # 这个过滤器是谷歌推荐的算法,一般不做更改 232 | -optimizations !code/simplification/cast,!field/*,!class/merging/* 233 | 234 | 235 | ####################Android开发中需要保留的公共部分#################### 236 | 237 | # 保留support下的所有类及其内部类 238 | -keep class android.support.** {*;} 239 | # 保留继承的support类 240 | -keep public class * extends android.support.v4.** 241 | -keep public class * extends android.support.v7.** 242 | -keep public class * extends android.support.annotation.** 243 | 244 | # 保留R下面的资源 245 | -keep class **.R$* {*;} 246 | 247 | # 保留本地native方法不被混淆 248 | -keepclasseswithmembernames class * { 249 | native ; 250 | } 251 | 252 | # 保留Activity中参数类型为View的所有方法 253 | -keepclassmembers class * extends android.app.Activity{ 254 | public void *(android.view.View); 255 | } 256 | 257 | # 保留枚举类不被混淆 258 | -keepclassmembers enum * { 259 | public static **[] values(); 260 | public static ** valueOf(java.lang.String); 261 | } 262 | 263 | # 保留Parcelable序列化类不被混淆 264 | -keep class * implements android.os.Parcelable { 265 | public static final android.os.Parcelable$Creator *; 266 | } 267 | 268 | # 保留Serializable序列化的类不被混淆 269 | -keepclassmembers class * implements java.io.Serializable { 270 | static final long serialVersionUID; 271 | private static final java.io.ObjectStreamField[] serialPersistentFields; 272 | !static !transient ; 273 | !private ; 274 | !private ; 275 | private void writeObject(java.io.ObjectOutputStream); 276 | private void readObject(java.io.ObjectInputStream); 277 | java.lang.Object writeReplace(); 278 | java.lang.Object readResolve(); 279 | } 280 | 281 | # 保留我们自定义控件(继承自View)不被混淆 282 | -keep public class * extends android.view.View{ 283 | *** get*(); 284 | void set*(***); 285 | public (android.content.Context); 286 | public (android.content.Context, android.util.AttributeSet); 287 | public (android.content.Context, android.util.AttributeSet, int); 288 | } 289 | 290 | # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆 291 | -keepclassmembers class * { 292 | void *(**On*Event); 293 | void *(**On*Listener); 294 | } 295 | 296 | # webView的混淆处理 297 | -keepclassmembers class fqcn.of.javascript.interface.for.webview { 298 | public *; 299 | } 300 | -keepclassmembers class * extends android.webkit.webViewClient { 301 | public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap); 302 | public boolean *(android.webkit.WebView, java.lang.String); 303 | } 304 | -keepclassmembers class * extends android.webkit.webViewClient { 305 | public void *(android.webkit.webView, jav.lang.String); 306 | } 307 | 308 | 309 | 310 | ############################################# 311 | # 312 | # 自定义的混淆配置(根据项目需求进行定义) 313 | # 314 | ############################################# 315 | 316 | # 不混淆log 317 | -assumenosideeffects class android.util.Log { 318 | public static boolean isLoggable(java.lang.String, int); 319 | public static int v(...); 320 | public static int i(...); 321 | public static int w(...); 322 | public static int d(...); 323 | public static int e(...); 324 | } 325 | 326 | 327 | 328 | ############################################# 329 | # 330 | # 第三方库的混淆配置(根据第三方库官网添加混淆代码) 331 | # 332 | ############################################# 333 | 334 | # Gson 335 | -keepattributes *Annotation* 336 | -keep class sun.misc.Unsafe { *; } 337 | -keep class com.idea.fifaalarmclock.entity.*** 338 | -keep class com.google.gson.stream.** { *; } 339 | -keep class com.你的bean.** { *; } 340 | 341 | 342 | # OkHttp3 343 | -dontwarn okhttp3.logging.** 344 | -keep class okhttp3.internal.**{*;} 345 | -dontwarn okio.** 346 | 347 | 348 | # Retrofit 349 | -dontwarn retrofit2.** 350 | -keep class retrofit2.** { *; } 351 | -keepattributes Signature 352 | -keepattributes Exceptions 353 | 354 | 355 | # RxJava RxAndroid 356 | -dontwarn sun.misc.** 357 | -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { 358 | long producerIndex; 359 | long consumerIndex; 360 | } 361 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { 362 | rx.internal.util.atomic.LinkedQueueNode producerNode; 363 | } 364 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { 365 | rx.internal.util.atomic.LinkedQueueNode consumerNode; 366 | } 367 | 368 | # Glide图片库 369 | -keep class com.bumptech.glide.**{*;} 370 | 371 | ``` 372 | -------------------------------------------------------------------------------- /proguard-rules.pro: -------------------------------------------------------------------------------- 1 | ############################################# 2 | # 3 | # 基础混淆配置 4 | # 5 | ############################################# 6 | 7 | 8 | ####################基本混淆指令的设置#################### 9 | 10 | # 代码混淆压缩比,在0~7之间,默认为5,一般不做修改 11 | -optimizationpasses 5 12 | 13 | # 混合时不使用大小写混合,混合后的类名为小写 14 | -dontusemixedcaseclassnames 15 | 16 | # 优化时允许访问并修改有修饰符的类和类的成员 17 | -allowaccessmodification 18 | 19 | # 指定不忽略非公共库的类 20 | -dontskipnonpubliclibraryclasses 21 | 22 | # 指定不忽略非公共库的类成员 23 | -dontskipnonpubliclibraryclassmembers 24 | 25 | # 记录日志,使我们的项目混淆后产生映射文件(类名->混淆后类名) 26 | -verbose 27 | 28 | # 忽略警告,避免打包时某些警告出现,没有这个的话,构建报错 29 | -ignorewarnings 30 | 31 | # 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。 32 | -dontpreverify 33 | 34 | # 不混淆Annotation(保留注解) 35 | -keepattributes *Annotation*,InnerClasses 36 | 37 | # 避免混淆泛型 38 | -keepattributes Signature 39 | 40 | # 抛出异常时保留代码行号 41 | -keepattributes SourceFile,LineNumberTable 42 | 43 | # 指定混淆是采用的算法,后面的参数是一个过滤器 44 | # 这个过滤器是谷歌推荐的算法,一般不做更改 45 | -optimizations !code/simplification/cast,!field/*,!class/merging/* 46 | 47 | 48 | ####################Android开发中需要保留的公共部分#################### 49 | 50 | # 保留support下的所有类及其内部类 51 | -keep class android.support.** {*;} 52 | # 保留继承的support类 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 | 57 | # 保留R下面的资源 58 | -keep class **.R$* {*;} 59 | 60 | # 保留本地native方法不被混淆 61 | -keepclasseswithmembernames class * { 62 | native ; 63 | } 64 | 65 | # 保留Activity中参数类型为View的所有方法 66 | -keepclassmembers class * extends android.app.Activity{ 67 | public void *(android.view.View); 68 | } 69 | 70 | # 保留枚举类不被混淆 71 | -keepclassmembers enum * { 72 | public static **[] values(); 73 | public static ** valueOf(java.lang.String); 74 | } 75 | 76 | # 保留Parcelable序列化类不被混淆 77 | -keep class * implements android.os.Parcelable { 78 | public static final android.os.Parcelable$Creator *; 79 | } 80 | 81 | # 保留Serializable序列化的类不被混淆 82 | -keepclassmembers class * implements java.io.Serializable { 83 | static final long serialVersionUID; 84 | private static final java.io.ObjectStreamField[] serialPersistentFields; 85 | !static !transient ; 86 | !private ; 87 | !private ; 88 | private void writeObject(java.io.ObjectOutputStream); 89 | private void readObject(java.io.ObjectInputStream); 90 | java.lang.Object writeReplace(); 91 | java.lang.Object readResolve(); 92 | } 93 | 94 | # 保留我们自定义控件(继承自View)不被混淆 95 | -keep public class * extends android.view.View{ 96 | *** get*(); 97 | void set*(***); 98 | public (android.content.Context); 99 | public (android.content.Context, android.util.AttributeSet); 100 | public (android.content.Context, android.util.AttributeSet, int); 101 | } 102 | 103 | # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆 104 | -keepclassmembers class * { 105 | void *(**On*Event); 106 | void *(**On*Listener); 107 | } 108 | 109 | # webView的混淆处理 110 | -keepclassmembers class fqcn.of.javascript.interface.for.webview { 111 | public *; 112 | } 113 | -keepclassmembers class * extends android.webkit.webViewClient { 114 | public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap); 115 | public boolean *(android.webkit.WebView, java.lang.String); 116 | } 117 | -keepclassmembers class * extends android.webkit.webViewClient { 118 | public void *(android.webkit.webView, jav.lang.String); 119 | } 120 | 121 | 122 | 123 | ############################################# 124 | # 125 | # 自定义的混淆配置(根据项目需求进行定义) 126 | # 127 | ############################################# 128 | 129 | # 不混淆log 130 | -assumenosideeffects class android.util.Log { 131 | public static boolean isLoggable(java.lang.String, int); 132 | public static int v(...); 133 | public static int i(...); 134 | public static int w(...); 135 | public static int d(...); 136 | public static int e(...); 137 | } 138 | 139 | 140 | 141 | ############################################# 142 | # 143 | # 常用的第三方库混淆配置(根据第三方库官网添加混淆代码) 144 | # 145 | ############################################# 146 | 147 | # AndroidEventBus 148 | -keep class org.simple.** { *; } 149 | -keep interface org.simple.** { *; } 150 | -keepclassmembers class * { 151 | @org.simple.eventbus.Subscriber ; 152 | } 153 | 154 | 155 | # 百度地图(jar包换成自己的版本,记得签名要匹配) 156 | -libraryjars libs/baidumapapi_v2_1_3.jar 157 | -keep class com.baidu.** {*;} 158 | -keep class vi.com.** {*;} 159 | -keep class com.sinovoice.** {*;} 160 | -keep class pvi.com.** {*;} 161 | -dontwarn com.baidu.** 162 | -dontwarn vi.com.** 163 | -dontwarn pvi.com.** 164 | 165 | 166 | # BRVAH 167 | -keep class com.chad.library.adapter.** { *; } 168 | -keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter 169 | -keep public class * extends com.chad.library.adapter.base.BaseViewHolder 170 | -keepclassmembers public class * extends com.chad.library.adapter.base.BaseViewHolder { 171 | (android.view.View); 172 | } 173 | 174 | 175 | # Bugly 176 | -dontwarn com.tencent.bugly.** 177 | -keep class com.tencent.bugly.** {*;} 178 | 179 | 180 | # ButterKnife 181 | -keep public class * implements butterknife.Unbinder { 182 | public (**, android.view.View); 183 | } 184 | -keep class butterknife.* 185 | -keepclasseswithmembernames class * { 186 | @butterknife.* ; 187 | } 188 | -keepclasseswithmembernames class * { 189 | @butterknife.* ; 190 | } 191 | 192 | 193 | # Dagger2 194 | -dontwarn com.google.errorprone.annotations.* 195 | 196 | 197 | # EventBus 198 | -keepattributes *Annotation* 199 | -keepclassmembers class ** { 200 | @org.greenrobot.eventbus.Subscribe ; 201 | } 202 | -keep enum org.greenrobot.eventbus.ThreadMode { *; } 203 | 204 | 205 | # Facebook 206 | -keep class com.facebook.** {*;} 207 | -keep interface com.facebook.** {*;} 208 | -keep enum com.facebook.** {*;} 209 | 210 | 211 | # FastJson 212 | -dontwarn com.alibaba.fastjson.** 213 | -keep class com.alibaba.fastjson.** { *; } 214 | -keepattributes Signature 215 | -keepattributes *Annotation* 216 | 217 | 218 | # Fresco 219 | -keep class com.facebook.fresco.** {*;} 220 | -keep interface com.facebook.fresco.** {*;} 221 | -keep enum com.facebook.fresco.** {*;} 222 | 223 | 224 | # 高德相关依赖 225 | # 集合包:3D地图3.3.2 导航1.8.0 定位2.5.0 226 | -dontwarn com.amap.api.** 227 | -dontwarn com.autonavi.** 228 | -keep class com.amap.api.**{*;} 229 | -keep class com.autonavi.**{*;} 230 | # 地图服务 231 | -dontwarn com.amap.api.services.** 232 | -keep class com.map.api.services.** {*;} 233 | # 3D地图 234 | -dontwarn com.amap.api.mapcore.** 235 | -dontwarn com.amap.api.maps.** 236 | -dontwarn com.autonavi.amap.mapcore.** 237 | -keep class com.amap.api.mapcore.**{*;} 238 | -keep class com.amap.api.maps.**{*;} 239 | -keep class com.autonavi.amap.mapcore.**{*;} 240 | # 定位 241 | -dontwarn com.amap.api.location.** 242 | -dontwarn com.aps.** 243 | -keep class com.amap.api.location.**{*;} 244 | -keep class com.aps.**{*;} 245 | # 导航 246 | -dontwarn com.amap.api.navi.** 247 | -dontwarn com.autonavi.** 248 | -keep class com.amap.api.navi.** {*;} 249 | -keep class com.autonavi.** {*;} 250 | 251 | 252 | # Glide 253 | -keep public class * implements com.bumptech.glide.module.GlideModule 254 | -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { 255 | **[] $VALUES; 256 | public *; 257 | } 258 | 259 | 260 | ### greenDAO 3 261 | -keepclassmembers class * extends org.greenrobot.greendao.AbstractDao { 262 | public static java.lang.String TABLENAME; 263 | 94 } 264 | -keep class **$Properties 265 | 266 | # If you do not use SQLCipher: 267 | -dontwarn org.greenrobot.greendao.database.** 268 | # If you do not use RxJava: 269 | -dontwarn rx.** 270 | 271 | 272 | # Gson 273 | -keepattributes Signature 274 | -keepattributes *Annotation* 275 | -keep class sun.misc.Unsafe { *; } 276 | -keep class com.google.gson.stream.** { *; } 277 | # 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。 278 | # 将下面替换成自己的实体类 279 | #-keep class com.example.bean.** { *; } 280 | 281 | 282 | # Jackson 283 | -dontwarn org.codehaus.jackson.** 284 | -dontwarn com.fasterxml.jackson.databind.** 285 | -keep class org.codehaus.jackson.** { *;} 286 | -keep class com.fasterxml.jackson.** { *; } 287 | 288 | 289 | # 极光推送 290 | -dontoptimize 291 | -dontpreverify 292 | -dontwarn cn.jpush.** 293 | -keep class cn.jpush.** { *; } 294 | 295 | 296 | # OkHttp 297 | -dontwarn okio.** 298 | -dontwarn okhttp3.** 299 | -dontwarn javax.annotation.Nullable 300 | -dontwarn javax.annotation.ParametersAreNonnullByDefault 301 | 302 | 303 | # Okio 304 | -dontwarn com.squareup.** 305 | -dontwarn okio.** 306 | -keep public class org.codehaus.* { *; } 307 | -keep public class java.nio.* { *; } 308 | 309 | 310 | # OrmLite 311 | -keepattributes *DatabaseField* 312 | -keepattributes *DatabaseTable* 313 | -keepattributes *SerializedName* 314 | -keep class com.j256.** 315 | -keepclassmembers class com.j256.** { *; } 316 | -keep enum com.j256.** 317 | -keepclassmembers enum com.j256.** { *; } 318 | -keep interface com.j256.** 319 | -keepclassmembers interface com.j256.** { *; } 320 | 321 | 322 | # Realm 323 | -keep class io.realm.annotations.RealmModule 324 | -keep @io.realm.annotations.RealmModule class * 325 | -keep class io.realm.internal.Keep 326 | -keep @io.realm.internal.Keep class * { *; } 327 | -dontwarn javax.** 328 | -dontwarn io.realm.** 329 | 330 | 331 | # Retrofit 332 | -keep class retrofit2.** { *; } 333 | -dontwarn retrofit2.** 334 | -keepattributes Signature 335 | -keepattributes Exceptions 336 | -dontwarn okio.** 337 | -dontwarn javax.annotation.** 338 | 339 | 340 | # Retrolambda 341 | -dontwarn java.lang.invoke.* 342 | 343 | 344 | # RxJava RxAndroid 345 | -dontwarn sun.misc.** 346 | -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { 347 | long producerIndex; 348 | long consumerIndex; 349 | } 350 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { 351 | rx.internal.util.atomic.LinkedQueueNode producerNode; 352 | } 353 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { 354 | rx.internal.util.atomic.LinkedQueueNode consumerNode; 355 | } 356 | -dontnote rx.internal.util.PlatformDependent 357 | 358 | 359 | # Universal-Image-Loader-v1.9.5 360 | -libraryjars libs/universal-image-loader-1.9.5-SNAPSHOT-with-sources.jar 361 | -dontwarn com.nostra13.universalimageloader.** 362 | -keep class com.nostra13.universalimageloader.** { *; } 363 | 364 | 365 | # 微信支付 366 | -dontwarn com.tencent.mm.** 367 | -dontwarn com.tencent.wxop.stat.** 368 | -keep class com.tencent.mm.** {*;} 369 | -keep class com.tencent.wxop.stat.**{*;} 370 | 371 | 372 | # 信鸽 373 | -keep public class * extends android.app.Service 374 | -keep public class * extends android.content.BroadcastReceiver 375 | -keep class com.tencent.android.tpush.** {* ;} 376 | -keep class com.tencent.mid.** {* ;} 377 | -keepattributes *Annotation* 378 | 379 | 380 | # 新浪微博 381 | -keep class com.sina.weibo.sdk.* { *; } 382 | -keep class android.support.v4.* { *; } 383 | -keep class com.tencent.* { *; } 384 | -keep class com.baidu.* { *; } 385 | -keep class lombok.ast.ecj.* { *; } 386 | -dontwarn android.support.v4.** 387 | -dontwarn com.tencent.**s 388 | -dontwarn com.baidu.** 389 | 390 | 391 | # XLog 392 | -keep class com.tencent.mars.** { *; } 393 | -keepclassmembers class com.tencent.mars.** { *; } 394 | -dontwarn com.tencent.mars.** 395 | 396 | 397 | # 讯飞语音 398 | -dontwarn com.iflytek.** 399 | -keep class com.iflytek.** {*;} 400 | 401 | 402 | # xUtils3.0 403 | -keepattributes Signature,Annotation 404 | -keep public class org.xutils.** { 405 | public protected *; 406 | } 407 | -keep public interface org.xutils.** { 408 | public protected *; 409 | } 410 | -keepclassmembers class * extends org.xutils.** { 411 | public protected *; 412 | } 413 | -keepclassmembers @org.xutils.db.annotation.* class * {;} 414 | -keepclassmembers @org.xutils.http.annotation. class * {*;} 415 | -keepclassmembers class * { 416 | @org.xutils.view.annotation.Event ; 417 | } 418 | 419 | 420 | # 银联 421 | -dontwarn com.unionpay.** 422 | -keep class com.unionpay.** { *; } 423 | 424 | 425 | # 友盟统计分析 426 | -keepclassmembers class * { public (org.json.JSONObject); } 427 | -keepclassmembers enum com.umeng.analytics.** { 428 | public static **[] values(); 429 | public static ** valueOf(java.lang.String); 430 | } 431 | 432 | 433 | # 友盟自动更新 434 | -keepclassmembers class * { public (org.json.JSONObject); } 435 | -keep public class cn.irains.parking.cloud.pub.R$*{ public static final int *; } 436 | -keep public class * extends com.umeng.** 437 | -keep class com.umeng.** { *; } 438 | 439 | 440 | # 支付宝钱包 441 | -dontwarn com.alipay.** 442 | -dontwarn HttpUtils.HttpFetcher 443 | -dontwarn com.ta.utdid2.** 444 | -dontwarn com.ut.device.** 445 | -keep class com.alipay.android.app.IAlixPay{*;} 446 | -keep class com.alipay.android.app.IAlixPay$Stub{*;} 447 | -keep class com.alipay.android.app.IRemoteServiceCallback{*;} 448 | -keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;} 449 | -keep class com.alipay.sdk.app.PayTask{ public *;} 450 | -keep class com.alipay.sdk.app.AuthTask{ public *;} 451 | -keep class com.alipay.mobilesecuritysdk.* 452 | -keep class com.ut.* 453 | --------------------------------------------------------------------------------