添加依赖:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt' // 如果使用Kotlin,需要kapt编译器插件
id 'dagger.hilt.android.plugin' // Hilt插件
}
dependencies {
implementation 'com.google.dagger:hilt-android:2.40.5' // Hilt核心库
kapt 'com.google.dagger:hilt-compiler:2.40.5' // 如果使用Kotlin,需要kapt编译器依赖
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0' // Hilt与ViewModel的集成库
implementation 'androidx.room:room-runtime:2.4.3' // Room运行时库
kapt 'androidx.room:room-compiler:2.4.3' // 如果使用Kotlin,需要kapt编译器依赖
}
使用Room的三个步骤:
第一,定义数据库(AppDatabase是自定义的数据库类名称)
定义一个Room数据库实体(例如UserEntity
)以及对应的Room数据库抽象类(例如AppDatabase
),并使用@Database
注解指定包含的实体类与版本信息。
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [UserEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
第二,创建数据的实体类Entity
@Entity:注解必须存在,这是实体类的标志,tableName 表名
@PrimaryKey:注解表示这个字段是主键,autoGenerate表示是自动增加的
@ColumnInfo:注解这个字段的别名,我们在其他地方就用这个别名。
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "users")
data class UserEntity(
@PrimaryKey(autoGenerate = true)
val id: Int,
val name: String,
val email: String
)
第三,定义一个Data Access Object (DAO) 接口(例如UserDao
),包含用于更新数据的方法等
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
@Dao
interface UserDao {
@Update
suspend fun updateUser(user: UserEntity)
@Insert
suspend fun insertUser(user: UserEntity)
@Query("SELECT * FROM users WHERE id=:id ")
suspend fun getUserById(id: Int): UserEntity?
}
第四创建Repository
创建一个Repository类(例如UserRepository
),它将作为ViewModel与Room数据库之间的中介。在这个类中,注入UserDao
并通过其方法执行数据更新操作。
class UserRepository @Inject constructor(private val userDao: UserDao) {
suspend fun updateUser(user: UserEntity) {
val data = userDao.getUserById(user.id!!)
if (data == null) {
userDao.insertUser(user)
} else {
userDao.updateUser(user)
}
}
}
第五:配置Hilt Modules
创建一个Hilt模块(例如DatabaseModule
),用于提供AppDatabase
实例。另外,可以创建另一个模块(例如RepositoryModule
)来提供UserRepository
实例。
// DatabaseModule.kt
@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
@Singleton
@Provides
fun provideDatabase(@ApplicationContext context: Context): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, "app_database.db")
.build()
}
@Singleton
@Provides
fun provideUserDao(database: AppDatabase): UserDao {
return database.userDao()
}
}
// RepositoryModule.kt
@Module
@InstallIn(SingletonComponent::class)
object RepositoryModule {
@Singleton
@Provides
fun provideUserRepository(userDao: UserDao): UserRepository {
return UserRepository(userDao)
}
}
第六:Hilt化ViewModel
使用@HiltViewModel
注解标记ViewModel类(例如UserViewModel
),并在其中注入所需的UserRepository
。
// UserViewModel.kt
@HiltViewModel
class UserViewModel @Inject constructor(private val userRepository: UserRepository) : ViewModel() {
fun updateUser(user: UserEntity) {
viewModelScope.launch {
userRepository.updateUser(user)
// 更新成功后,可以在此处触发LiveData或Flow等通知UI更新
}
}
}
第七:在Activity/Fragment/Compose中使用ViewModel
在使用Hilt的Activity或Fragment或者Compse中,通过by viewModels()
委托属性获取注入的UserViewModel
实例,并调用其updateUser
方法来更新Room中的数据。
class MainActivity : ComponentActivity() {
private val userViewModel: UserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Index(userViewModel)
}
}
}
}
@Composable
fun Index(userViewModel: UserViewModel) {
var username: String by remember { mutableStateOf("") }
var email: String by remember { mutableStateOf("") }
Column {
OutlinedTextField(value = username, onValueChange = {
username = it
userViewModel.updateUser(UserEntity(1, username, email))
})
OutlinedTextField(value = email, onValueChange = {
email = it
userViewModel.updateUser(UserEntity(1, username, email))
})
}
}
至此,您已经完成了在Android应用中使用Hilt依赖注入来更新Room数据库中数据的所有步骤。当updateUser
方法在ViewModel中被调用时,Hilt会确保所有依赖(如UserRepository
和UserDao
)已正确注入,并通过它们与Room数据库进行交互。