Fixed
Status Update
Comments
il...@google.com <il...@google.com>
il...@google.com <il...@google.com>
ap...@google.com <ap...@google.com> #2
Yigit, do you have time to fix it?
reemission of the same liveData is racy
reemission of the same liveData is racy
ap...@google.com <ap...@google.com> #4
Thanks for the detailed analysis. This may not be an issue anymore since we've started using Main.immediate there but I' not sure; I'll try to create a test case.
ap...@google.com <ap...@google.com> #5
just emitting same live data reproduces the issue.
@Test
fun raceTest() {
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData)
emitSource(subLiveData) //crashes
}
subject.addObserver().apply {
testScope.advanceUntilIdle()
}
}
@Test
fun raceTest() {
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData)
emitSource(subLiveData) //crashes
}
subject.addObserver().apply {
testScope.advanceUntilIdle()
}
}
Description
Version used: 1.2.4
Devices/Android versions reproduced on: any
Fragment.getDefaultViewModelProviderFactory() makes a call to requireActivity() in order to obtain an instance of Application. This will fail if the Fragment is hosted in a FragmentHostCallback that doesn't reference an Activity (i.e. its context is not an Activity). getDefaultViewModelProviderFactory() and onCreateContextMenu() (which doesn't make sense for non-Activity Fragments) are the only places requireActivity() is used. Everywhere else uses get/requireContext() or allows getActivity() to return null.
Because Fragments are so prevalent, this makes the entire HasDefaultViewModelProviderFactory interface untrustworthy in codebases that may have non-Activity Fragments.
A simple fix would be to return a NewInstanceFactory() if mFragmentManager is non-null but getActivity() is null. This wouldn't support AndroidViewModels, but other ViewModels would still be able to be instantiated. Expanding SavedStateViewModelFactory to not require an Application would also help since the SavedStateHandler infrastructure doesn't appear to require the Application for anything else. Ideally, the Application would be able to be obtained elsewhere for non-Activity Fragments, but not supporting AndroidViewModels would be an acceptable trade off if that's not possible.
A less ideal solution would be to add another constructor to AndroidViewModels that takes a Context for use when an Application is not available, but that would clutter the API and is probably not worth it.