Roomを利用する場合(1)
前回の図1のパターンで残っているのは、Roomの利用です。
Hilt+RoomでのAppDatabase
Roomを利用する場合、少しテクニックが必要です。というのは第2回で紹介したように、Roomの場合は、DAOをインターフェースで作成します。
また、AppDatabaseを抽象クラスで作成し、しかもシングルトンパターンでインスタンス生成を行う必要があります。この仕組みとHiltを組み合わせる場合、そもそもインスタンス生成がRoomに任せるため、Roomによって生成されたインスタンスをHiltによって注入させるコードパターンを取る必要があります。と同時に、シングルトンの仕組みもHiltに任せます。
そこでまず、AppDatabase内に、第2回のリスト7やリスト8のように、シングルトンパターンを組み込んだコードではなく、単にDAOインスタンスを生成するメソッドを定義したコードとします。
これは、Javaならばリスト5、Kotlinならばリスト6のコードです。
@Database(entities = {Cocktailmemo.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract CocktailmemoDAO createCocktailmemoDAO();
}
@Database(entities = [Cocktailmemo::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun createCocktailmemoDAO(): CocktailmemoDAO
}
モジュールの作成
代わりに、HiltによってAppDatabaseやDAOインスタンスを生成するモジュールを作成します。これは、Javaならばリスト7、Kotlinならばリスト8のコードとなります。
@Module // (1)
@InstallIn(SingletonComponent.class) // (2)
public class AppDatabaseModule { // (3)
@Provides // (4)
@Singleton // (5)
public AppDatabase provideDatabase(@ApplicationContext Context context) { // (6)
return Room.databaseBuilder(context, AppDatabase.class, "cocktailmemo_db").build(); // (7)
}
@Provides // (8)
public CocktailmemoDAO provideCocktailmemoDAO(AppDatabase db) { // (9)
return db.createCocktailmemoDAO(); // (10)
}
}
@Module // (1)
@InstallIn(SingletonComponent::class) // (2)
object AppDatabaseModule { // (3)
@Provides // (4)
@Singleton // (5)
fun provideDatabase(@ApplicationContext context: Context): AppDatabase { // (6)
return Room.databaseBuilder(context, AppDatabase::class.java, "cocktailmemo_db").build() // (7)
}
@Provides // (8)
fun provideCocktailmemoDAO(db: AppDatabase): CocktailmemoDAO { // (9)
return db.createCocktailmemoDAO() // (10)
}
}
リスト7、およびリスト8のポイントは、次の通りです。
クラス/オブジェクトを作成する
(3)の通り、Javaの場合はクラスで、Kotlinの場合はオブジェクトとして生成します。その名称はなんでもかまいません。
ただし、(1)のように@Moduleアノテーションを付与します。また、@InstallInアノテーションを付与し、このモジュールが属するスコープを指定します。その引数としてSingletonComponentクラスを指定することで、このモジュールがシングルトンスコープに属すことになり、結果、後述する@Singletonが利用できるようになります。
インスタンス生成メソッドに@Providesアノテーションを付与する。
(4)と(8)が該当します。
AppDatabaseを生成するメソッドを定義する。
(6)が該当します。その際、引数としてContextを定義し、それを(7)のAppDatabaseの生成コードで利用します。ただし、このContext引数に@ApplicationContextアノテーションを付与しておかないとApplicationContextが渡されないので注意してください。
また、このメソッドによって生成されるAppDatabaseインスタンスこそ、シングルトンの必要があるので(5)のように@Singletonアノテーションを付与します。
DAOインスタンス生成メソッドを定義する。
(9)が該当します。その際、AppDatabaseを引数とします。そして、メソッド内部では(10)のようにAppDatabaseの引数を利用して、DAOインスタンスの生成コードを記述します。
