はじめに
本記事は、CodelabsのAndroidアプリでのHiltの使用をやってみた際のログです。
詰まった箇所について述べています。
実行環境
PC: MacBook Air (M1, 2020)
OS: macOS Big Sur 11.5.2
チップ: Apple M1
メモリ: 16 GB
Android Studio:
Android Studio Arctic Fox | 2020.3.1 Patch 2
Build #AI-203.7717.56.2031.7678000, built on August 27, 2021
Runtime version: 11.0.10+0-b96-7249189 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 11.5.2
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 8
Registry: external.system.auto.import.disabled=true
Non-Bundled Plugins: IdeaVIM, Dart, wu.seal.tool.jsontokotlin, org.jetbrains.kotlin, io.flutter, com.jetbrains.kmm
やってみる
実際にCodelabsの通りにやってみる。
設定方法
リポジトリをクローンして実行してみる。
git clone https://github.com/googlecodelabs/android-hilt
kaptのエラー
実行しようとしたところ、以下のkaptのエラーが出力された。
Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction
> java.lang.reflect.InvocationTargetException (no error message)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
stacktraceオプションを用いて、詳細なエラーログを出力したところ、以下のエラーが出力された。
Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction
> java.lang.reflect.InvocationTargetException (no error message)
* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:kaptDebugKotlin'.
・・・
Caused by: java.lang.Exception: No native library is found for os.name=Mac and os.arch=aarch64. path=/org/sqlite/native/Mac/aarch64
at org.sqlite.SQLiteJDBCLoader.loadSQLiteNativeLibrary(SQLiteJDBCLoader.java:333)
at org.sqlite.SQLiteJDBCLoader.initialize(SQLiteJDBCLoader.java:64)
at androidx.room.verifier.DatabaseVerifier.<clinit>(DatabaseVerifier.kt:71)
... 50 more
kaptのエラーの対処
調べたところ、stack overflowのCaused by: java.lang.Exception: No native library is found for os.name=Mac and os.arch=aarch64. path=/org/sqlite/native/Mac/aarch64という記事を見つけた。
記事によると、kapt "org.xerial:sqlite-jdbc:3.34.0"
をroom-compilerの前に追加してやれば良いそうなので追加してみる。
変更を加えたbuild.gradle(:app)
のRoomのdependencies部分を以下に示す。
// Room
kapt "org.xerial:sqlite-jdbc:3.34.0"
implementation "androidx.room:room-runtime:2.3.0"
kapt "androidx.room:room-compiler:2.3.0"
再度実行
再度、実行してみると実行することができた。
プロジェクトへの Hilt の追加
読むだけ。
アプリでの Hilt
@HiltAndroidApp
を加えるだけ。
Hilt を使用したフィールド注入
LogsFragment
LogsFragment
に@AndroidEntryPoint
を加える。
logger
とdateFormatter
に@Inject
を加える。
populateFields
を削除する。
DateFormatter
DateFormatter
のコンストラクタに@Inject
を加える。
LoggerLocalDataSource
LoggerLocalDataSource
のコンストラクタに@Inject
を加える。
インスタンスのスコープのコンテナに対する設定
LoggerLocalDataSourceの@Singletonを加える。
Hilt モジュール
モジュールの作成
DatabaseModule
を作成しようとしたところ、ApplicationComponent
が存在していなかった。
調べたところ、stack overflowのerror: cannot find symbol @dagger.hilt.InstallIn(value = {ApplicationComponent.class})にて、Dagger Version 2.30にてDeprecated、Dagger Version 2.31にて削除されている。
ApplicationComponent
の代わりに、SingletonComponent
を使えとのこと。
@Provide を使用したインスタンスの提供
provideLogDao
を作成。
provideDatabase
を作成。
アプリの実行
MainActivity
に@AndroidEntryPoint
を加える。
@Bind を使用したインターフェースの提供
NavigationModule
を作成。
AppNavigatorImpl
に@Inject
を加える。
MainActivity
のAppNavigator
に@Inject
を加える。
ButtonsFragment
に@AndroidEntryPoint
を加える。
ButtonsFragment
のLoggerLocalDataSource
とAppNavigator
に@Inject
を加え、不要なメソッドを削除。
LogApplication
からServiceLocator
の使用を削除。
識別子
LoggerDataSource
を作成。
LogsFragment
のlogger
変数の型をLoggerDataSource
に設定。
ButtonsFragment
のlogger
変数の型をLoggerDataSource
に設定。
LoggerLocalDataSource
のインターフェースを実装。
LoggerInMemoryDataSource
を作成。
LoggerInMemoryDataSource
に@Inject
と@ActivityScoped
を加える。
LoggingModule
の作成。
UI テスト
build.gradle(:app)
に以下のdependenciesを追加。
// Hilt testing dependency
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
// Make Hilt generate code in the androidTest folder
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
}
CustomTestRunner
を作成。
build.gradle(:app)
にtestInstrumentationRunner
を設定。
AppTest
に@HiltAndroidTest
を加え、hiltRule
を作成。
@EntryPoint アノテーション
LogDao
にselectAllLogsCursor
とselectLogById
を追加。
LogsContentProvider
を作成。
LogsContentProvider
にLogsContentProviderEntryPoint
を追加。
メモ
- abstract class
- interface
- annontation class
- LinkedListとArrayList