LoginSignup
6
2

More than 1 year has passed since last update.

【Android】Non-Transitive R Classes を有効にしてビルドを最適化する

Last updated at Posted at 2023-04-12

はじめに

間もなくリリースされると予想される Android Gradle Plugin (AGP) 8.0 から、ライブラリモジュールにおいて R クラスがデフォルトで非推移的になります。本記事では、Non-Transitive R Classes の概要と、マイグレーション手順、導入のメリットについてまとめます。

Non-Transitive R Classes とは

:library2:library1 の2つのモジュールがあり、:library2:library1 に依存しているとします。従来 R クラスは推移的だったため、:library1 にあるリソースであっても あたかも:library2にあるリソースであるかのように扱うことができました。

しかしこれにはパフォーマンス上の問題がありました。なぜならビルドをするたびにそのモジュールだけでなく、モジュールが依存するすべてのモジュールのリソース ID も生成する必要があるからです。結果的に実行ファイルのサイズが大きくなり、ビルド時間も長くなっていました。

ここで登場するのが Non-Tansitive R Classes です。名前の通り、R クラスを非推移的にすることで上記の問題を解決することができます。

Non-Transitive R Classes に移行する

Non-Transitive R Classes への移行手順を紹介します。やり方は簡単で、Android Studio でプロジェクトを開き、| Refactor | Migrate to Non-Transitive R Classes... | を押すだけです。

image.png

自動的に android.nonTransitiveRClass=true 追加され、推移的に参照されていたリソースはパッケージ名を含む完全修飾名を使って参照されるようになります。

参考
非常に大きいプロジェクトの場合、Android Studio がフリーズすることがあるようです。その場合はこちらの記事の方法が参考になります。 https://slack.engineering/its-a-non-transitive-r-class-world/

リソースの完全修飾名の解決策

完全修飾名を使用することは煩雑で冗長なため、import alias を使って解決することができます。下記にサンプルコードを示します。

// Before
val bg = com.github.maxfie1d.common.resources.R.drawable.background

// After
import com.github.maxfie1d.common.resources.R as CommonR
val bg = CommonR.drawable.background

注意
Import alias は Kotlin の機能であるため、Java で使用することができません。したがって Java では完全修飾名を使用する必要があります。

ビルド時間の変化

プロジェクトによって異なりますが、Web で調べた限りでは インクリメンタルビルドにおいて 10%~20% 程度のパフォーマンス向上 を期待できるようです。機会があれば、手元のプロジェクトにおいてもパフォーマンス計測してみようと思います。

参考

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2