[英]LiveData observer is not removed
我正在嘗試在ViewModel
中獲取LiveData
更新,並確保觀察者沒有泄漏,但它正在泄漏。 典型的問題是觀察者沒有存儲在變量中,但這里不是這種情況; lambda 存儲在一個變量中。
private val observer: (List<MusicFile>) -> Unit =
{ musicFiles: List<MusicFile> ->
_uiState.postValue(FragmentMusicListState(musicFiles))
}
init {
musicRepository.musicFiles.observeForever(observer)
}
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
public override fun onCleared() {
super.onCleared()
musicRepository.musicFiles.removeObserver(observer)
}
問題是在調用 onCleared 之后,觀察者仍然依附。 我通過以下測試驗證了這一點。
@Test
fun onCleared_RemovesObserver() {
val musicRepository = MusicRepository.getInstance()
val context = InstrumentationRegistry.getInstrumentation().targetContext
musicRepository.loadMusicFiles(context.contentResolver)
val musicFiles = musicRepository.musicFiles
val viewModel = FragmentMusicListViewModel(SavedStateHandle(), musicRepository)
viewModel.onCleared()
assert(!musicFiles.hasObservers())
}
另外,我已經調試了最后一行的測試,musicFile 的屬性顯示觀察者仍然是附加的。 屬性 mActiveCount 和 mObservers 顯示觀察者仍然依附,
我如何真正刪除觀察者?
LiveData 在 observeForever 和 removeObserver 中接受類型為Observer<T>
的參數。 Observer是Kotlin認為Java寫在androidx.lifecycle庫中的一個函數式接口。
您傳入的是(List<MusicFile>) -> Unit
類型。
這是一個高階 function 並且與Observer<List<MusicFile>>
不是同一類型。 它們在功能上相似,因為它們都有一個類型為List<MusicFile>
的參數並且都返回Unit
,所以 Kotlin 的作用是好是壞(在這種情況下更糟)是它會為你“轉換”類型.
當 Kotlin 從高階 function“轉換”到功能接口時,它正在創建一個新的 object。當調用 observeForever 或 removeObserver 時,代碼中每次都會發生這種情況。 這就是 removeObserver 不起作用的原因,因為無論代碼看起來如何,您實際上並沒有傳遞相同的 object 。 我以前寫過這個。
簡而言之,您可以通過將觀察者的類型更改為觀察者來解決您的問題:
private val observer: Observer<List<MusicFile>> =
Observer { musicFiles: List<MusicFile> ->
// _uiState.postValue(FragmentMusicListState(musicFiles))
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.