I'm facing a very strange behavior when using Kotlin Coroutines Flow, Room and Live Data. Whenever I turn off my device for about 5-10s and turn it back on, the Coroutines Flow re-run all over again without any trigger. I'm not sure if it's a feature provided by Google or not. My code is as below.
MainActivity
wordViewModel = ViewModelProvider(this).get(WordViewModel::class.java)
wordViewModel.allWords.observe(this, Observer { words ->
words?.let { adapter.setWords(it) }
})
WordViewModel
class WordViewModel(private val repository: WordRepository) : ViewModel() {
val allWords = repository.allWords.onEach { Log.v("WordViewModel", "Flow trigger again") }.asLiveData()
}
WordRepository
class WordRepository(private val wordDao: WordDao) {
val allWords: Flow<List<Word>> = wordDao.getAlphabetizedWords()
suspend fun insert(word: Word) {
wordDao.insert(word)
}
}
WordDao
@Dao
interface WordDao {
@Query("SELECT * from word_table ORDER BY word ASC")
fun getAlphabetizedWords(): Flow<List<Word>>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(word: Word)
}
Word
@Entity(tableName = "word_table")
data class Word(@PrimaryKey @ColumnInfo(name = "word") val word: String)
The LogCat V/WordViewModel: Flow trigger again will be printed out again when I turn off my device for about 5-10s and turn it back on. Also, the device I'm using to test is Sony XZ2 run on Android 10.
If anyone know why this is happening, please help me understand. Thanks and sorry for my english.
EDIT
As the answer from @Alex Krafts, this feature is provided by Google. But because of my Kotlin Coroutines Flow will be combine with a network request. Therefore, I don't want it run again when device become active. I wrote a custom asLiveData() extension function for this case as follow.
LiveDataExtension
fun <T> Flow<T>.asLiveData(scope: CoroutineScope): LiveData<T> {
val liveData = MutableLiveData<T>()
scope.launch {
collect {
liveData.value = it
}
}
return liveData
}
WordViewModel
class WordViewModel(private val repository: WordRepository) : ViewModel() {
val allWords = repository.allWords.onEach { Log.v("WordViewModel", "Flow trigger again") }.asLiveData(viewModelScope)
}