AndroidKotlin

Room sous Kotlin

By 13 novembre 2018 No Comments

Utilisation de la librairie Room avec RxJava sous KOTLIN

Liste de liens utiles devant être déplacés de cet article.

https://github.com/googlesamples/android-architecture-components/tree/master/BasicRxJavaSampleKotlin/#readme

https://medium.com/androiddevelopers/room-rxjava-acb0cd4f3757

https://medium.com/@iammert/offline-app-with-rxjava-2-and-room-ccd0b5c18101

https://codinginfinite.com/android-room-persistent-rxjava/

https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#0

 


Cet article s’appuie sur l’article du codelabs de google « Android Room with a view Kotlin » disponible sur ce lien

 

Je ne vais pas réécrire l’article ci-dessus, celui-ci étant très bien détaillé. Cependant, voici vous trouverez ce qu’implique l’utilisation de  MutableLiveData à la place de LiveData

Extrait de l’article de google :

If you use LiveData independently from Room, you have to manage updating the data.  LiveData has no publicly available methods to update the stored data.

If you, the developer, want to update the stored data, you must use MutableLiveData instead of LiveData. The MutableLiveData class has two public methods that allow you to set the value of a LiveData object, setValue(T) and  postValue(T). Usually, MutableLiveData is used in the ViewModel, and then the  ViewModel only exposes immutable  LiveData objects to the observers.

 

J’ai donc repris le projet de google, et voici les différences entre l’utilisation de LiveData et MutableLiveData. LiveData étant biensûr le choix a faire lors de l’utilisation de Room. Par contre cela pourra vous être utile si vous utilisez autre chose que Room (comme Realm par exemple).

 

Le projet est disponible ici.

Utilisation de LiveData

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)
       val adapter = WordListAdapter(this)
       recyclerView.adapter = adapter
       recyclerView.layoutManager = LinearLayoutManager(this)

       wordViewModel = ViewModelProviders.of(this).get(WordViewModel::class.java)

       wordViewModel.allWords.observe(this, Observer { words ->
           // Update the cached copy of the words in the adapter.
           words?.let { adapter.setWords(it) }
       })

       fab.setOnClickListener {
           val intent = Intent(this@MainActivity, NewWordActivity::class.java)
           startActivityForResult(intent, newWordActivityRequestCode)
       }
   }

Utilisation de MutableLiveData

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)
       val adapter = WordListAdapter(this)
       recyclerView.adapter = adapter
       recyclerView.layoutManager = LinearLayoutManager(this)

       wordViewModel = ViewModelProviders.of(this).get(WordViewModel::class.java)

       wordViewModel.allWords.observe(this, Observer { words ->
           // Update the cached copy of the words in the adapter.
           words?.let { adapter.setWords(it) }
       })

       // When we use MutableLiveData, need to get all words "manually"
       // Needed when we use MutableLiveData instead of LiveData
       wordViewModel.getAllWord()

       fab.setOnClickListener {
           val intent = Intent(this@MainActivity, NewWordActivity::class.java)
           startActivityForResult(intent, newWordActivityRequestCode)
       }
   }

WordViewModel.kt

var allWords: LiveData<List<Word>>

WordViewModel.kt

var allWords: MutableLiveData<List<Word>> = MutableLiveData()

WordRepository.kt

class WordRepository(private val wordDAO: IWordDao) {

    val allWords: LiveData<List<Word>> = wordDAO.getAllWords()

    @WorkerThread
    suspend fun insert(word: Word) {
        wordDAO.insert(word)
    }
}

WordRepository.kt

class WordRepository(private val wordDAO: IWordDao) {

    val allWords: MutableLiveData<List<Word>> = MutableLiveData()

    @WorkerThread
    suspend fun insert(word: Word) {
        wordDAO.insert(word)

        // When we use Room with LiveData, no need to update datas (words) to display them on the UI. It is done automatically
        // Needed when we user MutableLiveData instead of LiveData
        allWords.postValue(wordDAO.getAllWords())
    }

    // Needed when we user MutableLiveData instead of LiveData
    @WorkerThread
    suspend fun getWords() {
        allWords.postValue(wordDAO.getAllWords())
    }
}

IWordDao.kt

@Dao
interface IWordDao {

    @Query("SELECT * from word_table ORDER BY word ASC")
    fun getAllWords(): LiveData<List<Word>>

    @Insert
    fun insert(word: Word)

    @Query("DELETE FROM word_table")
    fun deleteAll()
}

IWordDao.kt

@Dao
interface IWordDao {

    // Needed when we user MutableLiveData instead of LiveData - Need to comment the 2 above line and uncomment 2 next lines
    @Query("SELECT * from word_table ORDER BY word ASC")
    fun getAllWords(): List<Word>

    @Insert
    fun insert(word: Word)

    @Query("DELETE FROM word_table")
    fun deleteAll()

}

Leave a Reply