毎回、RoomとHiltの設定が複雑なので、セットアップの手順をメモとして残しておきます。
目次
前提
アプリのアーキテクチャはMVVMで、次のような構成になります。
Gradleの設定
build.gradle
ファイルにRoomとHiltの依存関係を含める必要があります。
バージョンは環境に合わせて変えてください。
build.gradle(Projectレベル)
buildscript {
ext {
compose_ui_version = '1.2.0'
hilt_version = '2.44' // 追加
room_version = "2.6.1" // 追加
}
}
plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
id 'com.google.dagger.hilt.android' version "$hilt_version" apply false // 追加
}
build.gradle(Moduleレベル)
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt' // 追加
id 'com.google.dagger.hilt.android' // 追加
}
dependencies {
// Hilt-Dagger
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"
// Room
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// To use Kotlin annotation processing tool (kapt)
kapt("androidx.room:room-compiler:$room_version")
implementation "androidx.room:room-ktx:$room_version"
// compose viewmodel
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
// Coroutines(非同期処理を使う)
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.5.2"
・・・
}
これでSync
して正常にビルドができるか確認しましょう。
Roomの設定
1. Roomのデータエンティティを作成する
Roomで操作するデータのモデルを作成します。
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "user_name")
val name: String,
@ColumnInfo(name = "user_age")
val age: Int
)
2. DAO(データアクセスオブジェクト)を作成する
データベースを操作(CRUD処理)するためのインターフェースを作成します。
import androidx.room.*
import kotlinx.coroutines.flow.Flow
@Dao
interface UserDao {
// 全件取得
@Query("SELECT * FROM users")
fun getAllUsers(): Flow<List<User>>
// 1件取得
@Query("SELECT * FROM users where id = :id")
suspend fun getUserById(id:Long):Flow<User>
// 追加
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUser(user: User)
// 更新
@Update(onConflict = OnConflictStrategy.REPLACE)
suspend fun updateUser(user: User)
// 全件削除
@Query("DELETE FROM users")
suspend fun deleteAllUsers()
// 1件削除
@Delete
suspend fun deleteUser(user: User)
}
3. データベースを作成する
Roomのデータベースクラスを作成します。これには、データベースのバージョン、エンティティ、およびDAO(データアクセスオブジェクト)が含まれます。
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
Repositoryの作成
RepositoryはViewModelとDaoの間に位置し、2つのクラス間のやり取りを仲介します。
// UserRepository.kt
class UserRepository @Inject constructor(private val userDao: UserDao) {
fun getAllUsers(): Flow<List<User>> {
return userDao.getAllUsers()
}
fun getUserById(id: Int): Flow<User> {
return userDao.getUserById(id)
}
suspend fun insertUser(user:User) {
userDao.insertUser(wish)
}
suspend fun updateUser(user:User) {
userDao.updateUser(wish)
}
suspend fun deleteAllUsers() {
userDao.deleteAllUsers()
}
suspend fun deleteUser(user: User) {
userDao.deleteUser(user)
}
}
ViewModelの作成
UI層からRepositoryにアクセスするためにViewModelを作成します。
@HiltViewModel
class UserViewModel @Inject constructor(private val userRepository: UserRepository) : ViewModel() {
fun insertUser(user: User) {
viewModelScope.launch {
userRepository.insertUser(user)
}
}
fun deleteUser(user: User) {
viewModelScope.launch {
userRepository.deleteUser(user)
}
}
}
Hiltの設定
Moduleの作成
Hiltを使ってRoomのデータベースとDAOを注入可能にします。
// AppModule.kt
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun provideDatabase(@ApplicationContext context: Context): AppDatabase {
return Room.databaseBuilder(
context,
AppDatabase::class.java,
"app_database" // DB名
).build()
}
@Provides
fun provideUserDao(database: AppDatabase): UserDao {
return database.userDao()
}
}
HiltのApplicationクラスの拡張
// App.kt
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class App : Application()
AndroidManifest.xmlの修正
「HiltのApplicationクラスの拡張」で作成したクラス名をAndroidManifest.xmlの<application>
タグに追加します。
<application
android:name="App"
・・・
</application>
MainActivityの修正
既存のMainActivityにアノテーション@AndroidEntryPoint
を付けます。
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
全体の設定はざっくりとこんな感じです。
漏れがあれば、今後追記していきます。
Comment