当使用Kotlin流、Room和Live数据时,我面临着非常奇怪的行为。每当我关闭我的设备大约5-10秒,并打开它,协同工作的流量再次运行,没有任何触发。我不确定这是否是谷歌提供的功能。我的代码如下。
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)
LogCat V/WordViewModel: Flow trigger again
将再次打印出来,当我关闭我的设备大约5-10秒,并打开它。另外,我用来测试的设备是运行在Android 10上的索尼XZ2。
如果有人知道为什么会这样,请帮助我理解。谢谢,为我的英语道歉。
编辑
作为@Alex的回答,此功能由Google提供。但是由于我的Kotlin协同服务流将与网络请求结合在一起。因此,当设备激活时,我不希望它再次运行。我为本例编写了一个定制的asLiveData()扩展函数,如下所示。
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)
}
发布于 2020-02-28 05:45:12
这个功能确实是由Google提供的。您将提供MainActivity
(此)作为
wordViewModel.allWords.observe(this, Observer { words ->
因此,当您关闭设备屏幕时,活动(由于其自身的生命周期)停止观察allWords
,并在打开设备屏幕时再次观察它。所以你的日志就是从那里来的。
来自文档
取消后,如果LiveData再次活动,上游流收集将被重新执行。
https://stackoverflow.com/questions/60439871
复制相似问题