使用 WorkManager 更新 Room 中的数据库条目
Update database entry in Room using WorkManager
我正在尝试在 Android 中使用 WorkManager
,因为到目前为止我已经使用 AsyncTask
完成了插入更新。
我正在尝试更新 Room database
中的用户。我在 Repository
中创建了一个 class 来在后台执行该过程,但我不知道这是否是正确的编码方式。另外我有点困惑如何调用 userViewModel 中的方法。
这是我的代码:
在存储库中:
inner class Test(ctx: Context, params: WorkerParameters) : Worker(ctx, params) {
override fun doWork(): Result {
fun updateUser(userId : Int , userName :String , userLastname: String){
userDao.updateUser(userId, userName, userLastname)
}
return Result.success()
}
}
并且在视图模型中:
private val workManager: WorkManager = WorkManager.getInstance()
fun updateUser(userID: Int, userName: String, userLastname: String) {
workManager.enqueue(OneTimeWorkRequest.from(Repository.Test::class.java))
}
也许这不是使用 WorkManager 的正确方法,所以如果有人能帮助我,我将不胜感激。
Updated to support Coroutine Worker
您可以在稍作改动后使用您的代码。您可以使用 Data
class 将 userId、userName 等参数传递给 WorkManager
。也没有必要使 Worker
class 成为内部 class。基本上把它变成一个独立的 class.So,你 worker
class 看起来像:
TestWorker.kt
class TestWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result {
val userId = inputData.getInt("USER_ID")
val userName = inputData.getString("USER_NAME")
val userLastname = inputData.getString("USER_LAST_NAME")
AppDatabase.getInstance().userDao.updateUser(userId, userName, userLastname)
return Result.success()
}
}
TestViewModel.kt
class TestViewModel : ViewModel() {
fun updateUser(userId: Int, userName: String, userLastName: String) {
val worker = OneTimeWorkRequest.Builder(TestWorker::class.java)
val data = Data.Builder()
//Add parameter in Data class. just like bundle. You can also add Boolean and Number in parameter.
data.putInt("USER_ID", userId)
data.putString("USER_NAME", userName)
data.putString("USER_LAST_NAME", userLastName)
//Set Input Data
worker.setInputData(data.build())
//enque worker
WorkManager.getInstance().enqueue(worker.build())
}
}
Don't forget to make your database singleton like this:
@Database(entities = [User::class],
version = 1,
exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
// For Singleton instantiation
@Volatile
private var instance: AppDatabase? = null
fun getInstance(context: Context): AppDatabase {
return instance ?: synchronized(this) {
instance ?: buildDatabase(context).also { instance = it }
}
}
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context, AppDatabase::class.java, "userdb")
.build()
}
}
对于那些遇到错误 make doWork suspend
的人,您可以在下面摘录下面的答案。
class TestWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
val context = ctx
override suspend fun doWork(): Result {
val userId = inputData.getInt("USER_ID")
val userName = inputData.getString("USER_NAME")
val userLastname = inputData.getString("USER_LAST_NAME")
AppDatabase.getInstance(context).userDao.updateUser(userId, userName, userLastname)
return Result.success()
}
}
详细变化:
Worker CoroutineWorker
覆盖暂停 fun doWork(): 结果
我正在尝试在 Android 中使用 WorkManager
,因为到目前为止我已经使用 AsyncTask
完成了插入更新。
我正在尝试更新 Room database
中的用户。我在 Repository
中创建了一个 class 来在后台执行该过程,但我不知道这是否是正确的编码方式。另外我有点困惑如何调用 userViewModel 中的方法。
这是我的代码:
在存储库中:
inner class Test(ctx: Context, params: WorkerParameters) : Worker(ctx, params) {
override fun doWork(): Result {
fun updateUser(userId : Int , userName :String , userLastname: String){
userDao.updateUser(userId, userName, userLastname)
}
return Result.success()
}
}
并且在视图模型中:
private val workManager: WorkManager = WorkManager.getInstance()
fun updateUser(userID: Int, userName: String, userLastname: String) {
workManager.enqueue(OneTimeWorkRequest.from(Repository.Test::class.java))
}
也许这不是使用 WorkManager 的正确方法,所以如果有人能帮助我,我将不胜感激。
Updated to support
Coroutine Worker
您可以在稍作改动后使用您的代码。您可以使用 Data
class 将 userId、userName 等参数传递给 WorkManager
。也没有必要使 Worker
class 成为内部 class。基本上把它变成一个独立的 class.So,你 worker
class 看起来像:
TestWorker.kt
class TestWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result {
val userId = inputData.getInt("USER_ID")
val userName = inputData.getString("USER_NAME")
val userLastname = inputData.getString("USER_LAST_NAME")
AppDatabase.getInstance().userDao.updateUser(userId, userName, userLastname)
return Result.success()
}
}
TestViewModel.kt
class TestViewModel : ViewModel() {
fun updateUser(userId: Int, userName: String, userLastName: String) {
val worker = OneTimeWorkRequest.Builder(TestWorker::class.java)
val data = Data.Builder()
//Add parameter in Data class. just like bundle. You can also add Boolean and Number in parameter.
data.putInt("USER_ID", userId)
data.putString("USER_NAME", userName)
data.putString("USER_LAST_NAME", userLastName)
//Set Input Data
worker.setInputData(data.build())
//enque worker
WorkManager.getInstance().enqueue(worker.build())
}
}
Don't forget to make your database singleton like this:
@Database(entities = [User::class],
version = 1,
exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
// For Singleton instantiation
@Volatile
private var instance: AppDatabase? = null
fun getInstance(context: Context): AppDatabase {
return instance ?: synchronized(this) {
instance ?: buildDatabase(context).also { instance = it }
}
}
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context, AppDatabase::class.java, "userdb")
.build()
}
}
对于那些遇到错误 make doWork suspend
的人,您可以在下面摘录下面的答案。
class TestWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
val context = ctx
override suspend fun doWork(): Result {
val userId = inputData.getInt("USER_ID")
val userName = inputData.getString("USER_NAME")
val userLastname = inputData.getString("USER_LAST_NAME")
AppDatabase.getInstance(context).userDao.updateUser(userId, userName, userLastname)
return Result.success()
}
}
详细变化:
Worker CoroutineWorker
覆盖暂停 fun doWork(): 结果