Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update database entry in Room using WorkManager

I am trying to use WorkManager in Android because till now I have done my insert updates using AsyncTask. I'm trying to update user in Room database. I have created a class in Repository to do the process in background but I don't know if this is the right way to code. Also I am a bit confused how to call the method in userViewModel.

Here is my code:

In Repository:

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()
    }
}

And in viewModel:

private val workManager: WorkManager = WorkManager.getInstance()
fun updateUser(userID: Int, userName: String, userLastname: String)    {
    workManager.enqueue(OneTimeWorkRequest.from(Repository.Test::class.java))

}

Maybe this is not the right way to use WorkManager so I would appreciate it if anyone can help me.

like image 698
Jona Avatar asked Jan 25 '19 15:01

Jona


1 Answers

Updated to support Coroutine Worker

You can use your code with minor changes. You can pass your parameters like userId, userName etc to WorkManager using Data class. Also there is no need to make the Worker class an inner class. Just make it an independent class.So basically, you worker class would look something like:

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()
    }
}
like image 108
ankuranurag2 Avatar answered Nov 15 '22 07:11

ankuranurag2