一、Android混淆Proguard简介
在将Android应用打包成APP后,为了增加反编译后的代码阅读难度,通常会进行一些混淆操作。混淆的主要目的是将源代码中的类名、方法名和属性名替换为其他字符串(如a、b、c等),同时对代码进行压缩。这样一来,生成的APP文件体积会明显减小,从而达到优化APP的目的。
二、Proguard的作用
1. 压缩(Shrinking):默认开启,移除未使用的类和成员,并在优化(Optimization)之后再次执行,移除无用的类,减少APP中方法数,也可避免造成64K的问题。
2. 优化(Optimization):默认开启,字节码层级进行优化,加快应用运行速度。
3. 混淆(Obfuscation):默认开启,增大反编译难度,除了在混淆文件中添加keep保持的类和类成员都会被随机命名。这些功能都可以在proguard-rules.pro文件中重新定义进行关闭,但一般情况下不建议关闭它们,否则混淆将失去意义。
三、Android中开启混淆
要在Android项目中开启混淆,需要在项目的build.gradle文件中进行配置:
```groovy
minifyEnabled true // 开启压缩
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 使用R8编译器进行代码收缩、混淆和优化
```
在完成上述配置后,进行打包操作时,会在项目的proguard目录下生成3个文件:
1. proguard-android-optimize.txt:包含混淆规则的配置文件。
2. proguard-rules.pro:自定义混淆规则的配置文件。
3. proguard-output.jar:经过混淆后的APP文件。
在项目中,我们有一个名为`mapping.txt`的文件,它对项目中的类、属性、方法和混淆后的文件进行一一映射。这个文件非常重要,如果被别人拿到了,就可以根据里面的映射规则进行代码的还原。同时,我们还有一个名为`seeds.txt`的文件,其中包含了未混淆的类和成员。此外,还有一个名为`unused.txt`的文件,用于列出从APP中删除的代码。最后,我们有一个名为`proguard-rules.pro`的文件,用于存储ProGuard的配置规则。
基本规则如下:
1. 语法关键词:
- `keep`:保持类和类成员不被移除或重命名。
- `keepclassmembers`:保持类成员不被移除或重命名。
- `keepclasseswithmembers`:如果某成员存在,保持该类和类成员不被移除或重命名。
- `names`:防止被移出或重命名。
- `keepnames`:保持名称不变。
- `keepclassnames`:仅保留类名。
- `keepclasseswithmembernames`:如果存在某成员,保留该成员和类名。
2. 各种匹配符:
- `-keep class yc.com.physician.model.bean.*;`:保持继承了BaseActivity的public修饰的类名不被混淆。
- `-keep public class * extends yc.com.physician.base.BaseActivity`:内部类使用 $ 号,保持PhysicianWebSubjectActivity中内部类Test的所有public修饰的都不被混淆掉。
- `<init>`:匹配所有构造函数。
- `<fields>`:匹配所有成员变量。
- `<methods>`:匹配所有的方法。
- `-keep class yc.com.physician.ui.bean.User { public <methods>;}`:仅保留User类及其公共方法。
请根据提供的内容完成内容重构,并保持段落结构:
- 保留所有继承自com.bumptech.glide.module.AppGlideModule的类及其初始化方法;
- 保留User类的public修饰,参数为String类型的公共方法不被混淆;
- 保留所有native方法;
- 保留自定义数据模型bean目录下的所有类;
- 保留所有实现android.os.Parcelable接口的类及其静态常量创建器;
- 保留枚举enum类的所有公共静态方法;
- 保留yc.com.physician.ui.activity.PhysicianWebSubjectActivity$Test类的所有公共实例字段。
其他通用配置选项包括:
- verbose-dontnote [class filter]-dontwarn [class filter]-ignorewarnings-printconfiguration [filename]-dump [filename]
通用混淆规则如下:
在任何APP中都可以使用的混淆规则,需要时可直接复制使用。
```
#--------基本不用动区域--------------------------------------------
#---------------------------------基本指令区----------------------------------
#指定代码的压缩级别 -optimizationpasses 5
#包名不混合大小写 -dontusemixedcaseclassnames
#不去忽略非公共的库类 -dontskipnonpubliclibraryclasses
#优化 不优化输入的类文件 -dontoptimize
#预校验 -dontpreverify
#混淆时是否记录日志 -verbose
# 混淆时所采用的算法 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保护注解 -keepattributes *Annotation*
#忽略警告 -ignorewarning
##记录生成的日志数据,gradle build时在本项目根目录输出
## #apk 包内所有 class 的内部结构 -dump proguard/class_files.txt
#未混淆的类和成员 打印出那些被keep住的类和成员,结果输出到指定文件里。 -printseeds proguard/seeds.txt
#列出从 apk 中删除的代码 打印指定输出那些没用的代码(dead code)到文件中。 -printusage proguard/unused.txt
#混淆前后的映射 打印混淆前后的名称对应关系到文件中,以便crash后进行对照。 -printmapping proguard/mapping.txt
########记录生成的日志数据,gradle build时 在本项目根目录输出-end######
#如果引用了v4或者v7包 -dontwarn android.support.**
#———————————————————————————————————————————————
-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(); }
-keepclassmembers class **.R$* { pulic static <fields>; }
-keepclassmembers class * { void *(*Event); }
-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
#// natvie 方法不混淆
-keepclasseswithmembernames class * { native <methods>; }
#保持 Parcelable 不被混淆
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
#----------------------------------------------------------------------------
#-----------------------------------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); }
#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------
#-----------------------------------实体类-------------------------------------
```