当您使用 Android Gradle 插件 3.4.0 或更高版本构建项目时,不再使用 ProGuard 来执行编译时代码优化。相反,它与 R8 编译器协同工作以处理以下编译时任务:

```java

android {

buildTypes {

release {

// 仅在项目的发布构建类型中启用代码缩小、混淆和优化

minifyEnabled true

// 启用资源缩小,该操作由 Android Gradle 插件执行

shrinkResources true

// 包括与 Android Gradle 插件一起打包的默认 ProGuard 规则文件。要了解更多信息,请参阅有关 R8 配置文件的部分。

proguardFiles getDefaultProguardFile(

'proguard-android-optimize.txt'),

'proguard-rules.pro'

}

}

...

}

```

自定义要保留的资源:使用 `tools:keep` 和 `tools:discard` 标签来指定要保留或丢弃的资源。例如:

```groovy

tools:keep = "@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"

tools:discard = "@layout/unused2" />

```

关键字 `keep` 和 `keepclassmembers`,它们可以用来保护指定的类文件和类的成员。例如:

```groovy

keep {Modifier} {class_specification} 保护指定的类文件和类的成员

keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好

keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。

```

## keepnames

`keepnames` 命令用于保护指定的类和类的成员的名称,如果他们在压缩步骤中被删除。以下是 `keepnames` 命令的具体用法:

```bash

./apktool b obfuscate -s name -o output.apk input.apk --keepnames "com.example.MyClass"

```

此命令将对 `input.apk` 应用混淆,并保留指定类 `com.example.MyClass` 以及其所有成员的名称。最终生成的混淆后的 APK 文件将保存为 `output.apk`。

## keepclassmembernames

`keepclassmembernames` 命令与 `keepnames` 类似,但它仅保护指定类的成员名称,而不涉及类本身。以下是 `keepclassmembernames` 命令的具体用法:

```bash

./apktool b obfuscate -s name -o output.apk input.apk --keepclassmembernames "com.example.MyClass"

```

此命令将对 `input.apk` 应用混淆,并保留指定类 `com.example.MyClass` 的所有成员名称,而不影响类本身。最终生成的混淆后的 APK 文件将保存为 `output.apk`。

## printseeds

`printseeds` 命令用于列出在应用混淆时,哪些类和类的成员使用了 `-keepnames`、`-keepclassmembersnames` 或者 `-keepclasseswithmembernames` 选项。以下是 `printseeds` 命令的具体用法:

```bash

./apktool b obfuscate -s names --printseeds output.apk input.apk

```

此命令将对 `input.apk` 应用混淆,并输出在混淆过程中保留的类名和成员名清单到标准输出(即 `output.txt`)。最终生成的混淆后的 APK 文件将保存为 `output.apk`,清单信息将保存到 `output.txt`。

8 是 Google 开发的一个 Android 代码混淆工具,它可以移除 APK 中的无用代码,提高应用的安全性和运行性能。在使用 R8 进行混淆时,可以通过配置文件来自定义混淆规则和输出报告。下面是一个使用 R8 的简单示例:

首先,在模块的 `proguard-rules.pro` 文件中添加以下内容,以获取 R8 在构建项目时应用的所有规则的完整报告:

```

// You can specify any path and filename.

-printconfiguration tmp/full-r8-config.txt

```

接下来,创建一个名为 `mapping.txt` 的文件,列出原始的类、方法和字段名与混淆后代码之间的映射关系。这些映射关系将被用于生成混淆后的代码。例如:

```

original_class_name=obfuscated_class_name

method_name=method_name

field_name=field_name

```

然后,创建一个名为 `seeds.txt` 的文件,列出未被混淆的类和成员。这些类和成员将在混淆过程中保持不变。例如:

```

com.example.MyClass

public static final java.lang.String MY_FIELD = "my field";

```

最后,创建一个名为 `usage.txt` 的文件,列出从 APK 中删除的代码。这些代码将在混淆过程中被移除。例如:

```

com.example.MyClass.myMethod();

```

对于多模块项目,可以在子模块的 `build.gradle` 文件中添加以下配置:

```groovy

release {

consumerProguardFiles 'proguard-rules.pro'

}

```

这样,只要 app 模块开启了混淆,子模块无论是否打开混淆都会默认开启。请注意,子模块的混淆规则是无法影响 app 模块的,因此建议在子模块里尽量只放和子模块相关的混淆规则,一些公有的混淆方式请放在 app 或者公有的模块中。