Room Database with MVVM(Part-II)
In Previous Part we have completed basic setup of the Room Database,Now we are moving to how to integrate the ROOM database with MVVM pattern.
Dependancy that are required:
//Kotlin Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.3.1"
implementation 'android.arch.lifecycle:runtime:1.1.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
Repository:
Repository will be responsible for the all the data related operation,It will act as a middleware between fetching data from Api or from DB
class UserRepository(userDao:UserDao) {
val userDao: UserDao
init {
userDao = userDao
} suspend fun insertUser(user: User) {
userDao.insert(user)
} suspend fun getUsersList(): List<User> {
return userDao.getUsers();
}}
ViewModel:
It is a bridge between the View and Model(business logic). It does not have any clue which View has to use it as it does not have a direct reference to the View. So basically, the ViewModel should not be aware of the view who is interacting with. It interacts with the Model and exposes the observable that can be observed by the View.Do not pass context or view reference in viewmodel as it can lead to the memory leak.
class MainViewModel(userDatabase:UserDatabase) : ViewModel() {
val mListUsers: MutableLiveData<List<User>>
val mRepository: UserRepository
init {
mRepository = ReqresAPIRepo(application)
mListUsers = MutableLiveData()
} fun getUsers(): List<User> {
// Coroutine that will be canceled when the ViewModel iscleared.
viewModelScope.launch {
var listData=mRepository.getUsersList()
mListUsers.value=listData
} suspend fun inserUser(user:User):Boolean
{
try
{
mRepository.getUsersList(user)
return true
}catch(ex:Exception){
return false
}
}}
ViewModelFactory
This class will be responsible for creating viewmodel and providing it to view
class ViewModelFactory(userDatabase:UserDatabase) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if(modelClass.isAssignableFrom(MainViewModel::class.java)){
return MainViewModel(userDatabase) as T
}
throw IllegalArgumentException("Class not found")
}
}
Activity/Fragment
In your activity or fragment you need to write below code
class UserActivity : AppCompatActivity() {
lateinit var mainViewmodel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var db = LocalDatabase.getDatabase(this)
setContentView(R.layout.activity_main)
mainViewmodel = ViewModelProvider(
this,
ViewModelFactory(db)
).get(MainViewModel::class.java)
observeDataChagnes()
mainViewmodel.getListUsers()
}
fun observeDataChagnes() {
mainViewmodel.mListUsers.observe(this, Observer {data ->
//Here you will receive the list of users in data object,you can set adapter here or show in logs
// e.g adapter.updateData(data)
})
}
fun insertUser(user:User) {
var isSucced= mainViewmodel.inserUser(user) //this method return false if exception occer so you can show message
}
}
Thats it…Implemetation of Room and MVVM is Done