用R8优化和保护安卓应用
R8是一个用于缩减、保护和优化Android应用程序的工具。它使用proguard规则来改变应用程序的行为。
开发人员往往会把R8和proguard混淆。它们是相似的,但有一些细微的差别。在本教程的后面,我们将看到二者的区别。
目标
在本教程结束时,你应该对以下内容有所了解。
- 什么是R8。
- 什么是R8缩减。
- R8与proguard有什么区别。
- 如何在Android Studio中启用R8。
- R8如何用于缩减、优化和保护Android应用程序。
- R8使用的缩减应用程序的技术。
- Pro-guard规则和
@keep注释。 - 构建应用程序的发布版本。
什么是R8?
如前所述,R8是一个用于缩减、保护和优化Android应用程序的工具。
R8收缩意味着将应用程序的大小减少到更小的尺寸。基本上,我们减少应用程序的dex 文件的大小。
拥有一个小的应用程序对你和用户都是一种好处。这意味着会有更多的安装。此外,大多数人将有可能在他们的设备上保留你的应用程序。
R8与ProGuard有什么不同?
R8与proguard的区别在于以下几个方面。
- 与proguard相比,R8有更高的Kotlin语言支持。Proguard主要用于使用Java开发的应用程序。
- 通常情况下,R8的编译器比proguard的编译器要快很多。这使得R8的效率更高。同时,R8的构建时间也更短。
- 在缩减方面,R8比proguard更有效。它可以将一个应用程序缩减10%,而proguard可以将其缩减8%。
注意:对于gradle 3.4.0或更高版本,R8使用已经预定义的proguard规则。
在你的项目中启用R8
默认情况下,R8已经存在于Android Studio中。我们需要做的就是启用它。
要启用R8,请打开build.gradle 模块应用文件,在buildTypes 内添加这段代码。
android {
...
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
...
}
release{} 块内的代码意味着这将被应用到你的应用程序的发布构建版本中。如果你在模拟器中启动应用程序,这段代码不会被执行。
minifyEnabled 被设置为 ,这样它就可以执行R8的功能。true
shrinkResources 也被设置为 。这将删除你在应用程序中创建/添加的所有未使用的资源。true
在你想密集地优化你的代码并使其最小化的情况下,在gradle.properties 。
android.enableR8.fullMode = true
R8是如何用于缩减、优化和保护Android应用程序的?
让我们从缩减开始。
正如我们所提到的,R8在发布到Play商店供用户访问之前,用于缩减应用程序。在你的项目中启用它将删除所有未使用的类、函数和变量。此外,它还会删除所有你添加到项目中但从未使用过的资源。
当你不收缩你的应用程序时,你包含在你的应用程序中的所有第三方库将在其中占用一些空间。这将包括该库中未使用的方法和函数。
例如,当你用Kotlin创建一个应用程序时,你的应用程序将携带整个Kotlin-stdlib 。这显然会使你的应用程序变得非常大。请记住,你还可能使用了一些其他的库,如Androidx库、Jetpack库和Google Play服务。这样的应用程序在被缩小之前就已经非常大了。
优化
当你缩减你的应用程序时,你会优化你的代码。R8会检查、重写和重新排列你的代码,以提高代码效率。它还会处理可能存在的死代码。
安全性
为了提供安全性,R8提供了代码混淆功能。这意味着它将把你的应用程序中的所有类名、变量和函数,在构建应用程序的发布版本之前,将它们重命名为不可读的短名称。
这将防止恶意用户对你的应用程序进行反向工程。
以上所有的任务都是由R8编译器在编译时完成的。
R8缩减技术
R8有几种缩减技术,包括以下几种。
- 树形摇动技术
这项技术确保删除所有未使用的代码和结构。它对代码进行静态分析,删除实例化的类型和不可到达的代码。
- 优化技术
这种技术主要集中在以下方面。
- 删除死代码
- 有选择的内联
- 去除未使用的参数
- 类的合并
- 标识符重命名
这可以缩短类和包的名称。
- 减少调试信息
R8对调试信息进行规范化处理,并压缩调试号信息。
在某些情况下,一些代码结构不能通过上述技术删除。R8提供了另一种方法来处理这个问题;Class inlining 。这是一种试图删除只在内部使用的类的技术。
这样的类可能包括。
- 构建器。例如,
DatabaseBuilder和Retrofit.Builder。 - Lambdas。
这些类在运行时可能不需要,所以可能会减慢应用程序的构建时间。
类的内联重写代码的方式,可以删除不使用的构建器或Lambdas。
守护规则和@keep注解
R8使用proguard规则来优化你的代码。由于各种原因,重命名所有的类名并不总是可取的。但是,R8可能会删除一段你的应用程序实际需要的代码。这可能是因为R8没有正确检查你的代码。
注意:一定要测试你的应用程序,看它是否按预期工作。一个应用程序在其调试版本中可能不会崩溃,但在其发布版本中可能会崩溃。你可以随时生成一份关于删除代码的报告,看看哪些代码被R8删除。
为了解决R8摆脱需要的代码的问题,我们在proguard规则中添加-keep 行代码。
一个例子如下。
- keep class ClassName
这将告诉R8,名称为ClassName 的类不应该被混淆。另外,你可以在类里面添加一些函数,告诉R8保留这些函数。一个例子如下。
- keep class ClassName { fun myFunction() }
在上面的例子中,函数myFunction() 将不会被混淆。该类里面的其他函数将被混淆。
你也可以在一个类中使用@keep 注释,而不是在proguard文件中使用-keep 。添加@keep 注释后,R8不会对该类做任何事情。同样的情况也适用于你在函数或字段中添加它。
构建应用程序的发布版本
默认情况下,当你在Android Studio中构建一个应用程序时,它被构建为调试版本。为了将其构建为发布版本,你需要做以下工作。
- 点击Android Studio上的
build菜单,然后导航到选择构建变体。

- 选择构建变体,会出现活跃的构建变体。点击下拉菜单,选择发布版本。这将在其发布版本中重建你的应用程序。

总结
在本教程中,我们已经看到R8是一个用于缩减、优化、保护和混淆Android代码的工具。R8与proguard略有不同,尽管它使用ProGuard的规则来执行其任务。当比较这两者时,R8是杰出的,是优化和缩小你的应用程序大小的最佳工具。