Skip to content

Instantly share code, notes, and snippets.

@shohiebsense
Last active June 28, 2021 06:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shohiebsense/3e77a3ebf94f58b7738b96c71381af4d to your computer and use it in GitHub Desktop.
Save shohiebsense/3e77a3ebf94f58b7738b96c71381af4d to your computer and use it in GitHub Desktop.
Working with Coroutines, Room, LiveData
  1. Using Room, use the AndroidViewMode(application)
class YourModelViewModel(val database: YourModelDatabaseDao, 
                             application: Application) : AndroidViewModel(application){

}
  1. Add the ViewModelFactory
class YourModelViewModelFactory(
private val dataSource: YourModelDatabaseDao,  
private val application: Application) : ViewModelProvider.Factory {

  @Suppress("unchecked_cast")
   override fun <T : ViewModel?> create(modelClass: Class<T>): T {
       if (modelClass.isAssignableFrom(YourModelViewModel::class.java)) {
           return YourModelViewModel(dataSource, application) as T
       }
       throw IllegalArgumentException("Unknown ViewModel class")
   }

}

  1. Get your application instance through Activity/Fragment, and also
val application = requireNotNull(this.activity).application
val dataSource = YourDatabase.getInstance(application).yourModelDao
  1. Declare and Initialize the ViewModelFactory, onCreateView() after binding
val viewModelFactory = YourModelViewModelFactory(dataSource, application)
val yourModelViewModel =
       ViewModelProvider(
               this, viewModelFactory).get(YourModelViewModel::class.java)

  1. Add data binding to your fragment_name.xml
<data>
   <variable
       name="yourModelViewModel"
       type="com.shohiebsense.YourModelViewModel />
</data>

  1. Add this before return statement in ````onCreateView()```
binding.setLifecycleOwner(this)
  1. Add this before ViewModel initialization in onCreateView()
binding.sleepTrackerViewModel = sleepTrackerViewModel
  1. Clean and Rebuild

  2. In your interface Dao, add the suspend flags

@Dao
interface YourModelDao {
   @Insert
   suspend fun insert(model: YourModel

   @Update
   suspend fun update(model: YourModel)

   @Query("SELECT * from your_model_table WHERE id = :key")
   suspend fun get(key: Long): YourModel?

   @Query("DELETE FROM your_model_table")
   suspend fun clear()

   @Query("SELECT * FROM your_model_table" ORDER BY id DESC LIMIT 1")
   suspend fun getTonight(): SleepNight?

   //livedata already works inside suspend
   @Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC")
   fun getAllNights(): LiveData<List<SleepNight>>

}
  1. Add CoRoutines
  implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"

  // Kotlin Extensions and Coroutines support for Room
  implementation "androidx.room:room-ktx:$room_version"
  1. Define your model inside ViewModel
  private var yourModel = MutableLiveData<YourModel?>()

  1. It's an example to initialize your model
private fun initializeTonight() {
   viewModelScope.launch {
       tonight.value = getYourModelFromDatabase()
   }
}  
  
private suspend fun getTonightFromDatabase(): YourModel? { 
  var model = database.getYourModel()
       if (model?.attr != model?.anotherattr) {
           model = null
       }
       return model  
}
  
  fun onStartYourModel() {
		viewModelScope.launch {
			val yourModel = YourModel()
			insert(yourModel)
			yourModel.value = getTonightFromDatabase()
		}
	}

private suspend fun insert(model: YourModel) {
		database.insert(model)
	}

	private suspend fun update(model: YourModel){
		database.update(model)
	}

to trigger the call. inside the xml add

android:onClick="@{() -> yourModelViewModel.onStartYourModel()}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment