一、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); }

#----------------------------------------------------------------------------

#---------------------------------------------------------------------------------------------------

#-----------------------------------实体类-------------------------------------

```