BG_*_*eMe 5 android-room android-livedata kotlin-coroutines
在使用 Kotlin Coroutines Flow、Room 和 Live Data 时,我面临着一个非常奇怪的行为。每当我关闭我的设备大约 5-10 秒然后重新打开它时,协程流程就会重新运行而没有任何触发。我不确定这是否是 Google 提供的功能。我的代码如下。
主要活动
wordViewModel = ViewModelProvider(this).get(WordViewModel::class.java)
wordViewModel.allWords.observe(this, Observer { words ->
words?.let { adapter.setWords(it) }
})
Run Code Online (Sandbox Code Playgroud)
视图模型
class WordViewModel(private val repository: WordRepository) : ViewModel() {
val allWords = repository.allWords.onEach { Log.v("WordViewModel", "Flow trigger again") }.asLiveData()
}
Run Code Online (Sandbox Code Playgroud)
词库
class WordRepository(private val wordDao: WordDao) {
val allWords: Flow<List<Word>> = wordDao.getAlphabetizedWords()
suspend fun insert(word: Word) {
wordDao.insert(word)
}
}
Run Code Online (Sandbox Code Playgroud)
字道
@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)
}
Run Code Online (Sandbox Code Playgroud)
单词
@Entity(tableName = "word_table")
data class Word(@PrimaryKey @ColumnInfo(name = "word") val word: String)
Run Code Online (Sandbox Code Playgroud)
V/WordViewModel: Flow trigger again当我关闭我的设备大约 5-10 秒并重新打开它时,LogCat将再次打印出来。另外,我用来测试的设备是在 Android 10 上运行的 Sony XZ2。
如果有人知道为什么会这样,请帮助我理解。感谢和抱歉我的英语。
编辑
作为@Alex Krafts 的回答,此功能由 Google 提供。但是因为我的 Kotlin Coroutines Flow 会与网络请求结合。因此,当设备处于活动状态时,我不希望它再次运行。我为这种情况编写了一个自定义的 asLiveData() 扩展函数,如下所示。
实时数据扩展
fun <T> Flow<T>.asLiveData(scope: CoroutineScope): LiveData<T> {
val liveData = MutableLiveData<T>()
scope.launch {
collect {
liveData.value = it
}
}
return liveData
}
Run Code Online (Sandbox Code Playgroud)
视图模型
class WordViewModel(private val repository: WordRepository) : ViewModel() {
val allWords = repository.allWords.onEach { Log.v("WordViewModel", "Flow trigger again") }.asLiveData(viewModelScope)
}
Run Code Online (Sandbox Code Playgroud)
这个功能确实是Google提供的。您正在提供MainActivity(此),如下LifecycleOwner所示
wordViewModel.allWords.observe(this, Observer { words ->
Run Code Online (Sandbox Code Playgroud)
因此,当您关闭设备屏幕时,Activity(由于其自身的生命周期)将停止观察allWords,并在您重新打开设备屏幕时再次观察它。这就是您的日志的来源。
从文档中
取消后,如果LiveData再次激活,则会重新执行上游流量收集。
| 归档时间: |
|
| 查看次数: |
1867 次 |
| 最近记录: |