在升级我的Android项目使用AGP 8.0.0时,我注意到Android Build Analyzer建议使用非交易式R类来提高构建速度。
我很想知道它是什么以及它的工作原理。所以,我做了一些研究,这就是我发现的。
为什么
非传播R类已经存在了一段时间,但默认情况下没有启用。使用AGP 8.0.0,默认情况下启用了它。对于好奇的头脑,我提供了一个博客,该博客讨论了本文结尾处的R类和非传播R类的历史。
非传播R类启用每个库类的命名课程,以便其R类仅包含在库本身中声明的资源,而在库的依赖项中没有任何资源,从而降低了R类的大小对于那个库。
例如,如果代码使用来自androidx.navigation:navigation-ui-ktx
依赖项的默认动画R.anim.nav_default_enter_anim
。在不使用非传播R类的情况下,模块的“ R”类具有引用其自己的资源和对导航UI库资源的传递引用。
import com.learning.compose.R
...
.setStartAnimations(activity, R.anim.nav_default_enter_anim, R.anim.nav_default_exit_anim)
启用了非传递R类,这将迫使我们使用完全合格的R类名称访问依赖项模块中的资源,从而减少“ Compose”模块的“ R”类中的引用。而且,通过使用完全合格的R类名称引用,不必重新编译组合模块并提高了构建速度。
.setStartAnimations(activity, androidx.navigation.ui.R.anim.nav_default_enter_anim, androidx.navigation.ui.R.anim.nav_default_exit_anim)
由于依赖性通过非传播R类变得更加明确,因此代码的模块化增加了。由于资源不能来自传递依赖性,因此它也会降低复杂性。它还可以提高构建速度( clean 和增量),如Android Developers from Android Dev Summit '21所承诺的。
该怎么办
如果您使用来自另一个依赖关系/模块的资源,
- 如果您的Android项目仅100%Kotlin,那么您很幸运。您可以
alias
导入r类依赖项模块以访问该模块中的资源。 - 如果您的项目有一些Java代码参考,则必须使用完全合格的R类名称才能访问依赖项模块中的资源
另外,如果您使用另一个模块中的资源,但是您不声明对该模块的依赖性,并且不想声明依赖关系,则可以简单地在App Module中复制资源
怎么做
使用Android Studio的Refactor -> Migrate to non-transitive R classes
迁移该项目以使用非传播R类
-
这将是
- 在gradle.properties中添加以下内容
android.nonTransitiveRClass=true
- 更新完全合格的R类名称,无论其在哪里找到非传播R类用法
.setStartAnimations(activity, androidx.navigation.ui.R.anim.nav_default_enter_anim, androidx.navigation.ui.R.anim.nav_default_exit_anim)
此外,如果代码库在Kotlin中
import androidx.navigation.ui.R as NavUiR
...
.setStartAnimations(activity, NavUiR.anim.nav_default_enter_anim, NavUiR.anim.nav_default_exit_anim)
.setExitAnimations(activity, NavUiR.anim.nav_default_pop_enter_anim, NavUiR.anim.nav_default_pop_exit_anim)
这是我发现有用的文章的一些引用