Status Update
Comments
su...@google.com <su...@google.com> #2
reemission of the same liveData is racy
qu...@gmail.com <qu...@gmail.com> #3
jb...@google.com <jb...@google.com> #4
qu...@gmail.com <qu...@gmail.com> #5
@Test
fun raceTest() {
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData)
emitSource(subLiveData) //crashes
}
subject.addObserver().apply {
testScope.advanceUntilIdle()
}
}
jb...@google.com <jb...@google.com> #6
qu...@gmail.com <qu...@gmail.com> #7
I actually have a WIP fix for it:
if your case is the one i found (emitting same LiveData multiple times, as shown in #5) you can work around it by adding a dummy transformation.
val subLiveData = MutableLiveData(1)
val subject = liveData(testScope.coroutineContext) {
emitSource(subLiveData.map {it })
emitSource(subLiveData.map {it} )
}
jb...@google.com <jb...@google.com> #8
Branch: androidx-master-dev
commit af12e75e6b4110f48e44ca121466943909de8f06
Author: Yigit Boyar <yboyar@google.com>
Date: Tue Sep 03 12:58:11 2019
Fix coroutine livedata race condition
This CL fixes a bug in liveData builder where emitting same
LiveData source twice would make it crash because the second
emission registry could possibly happen before first one is
removed as source.
We fix it by using a suspending dispose function. It does feel
a bit hacky but we cannot make DisposableHandle.dispose async
and we do not want to block there. This does not mean that there
is a problem if developer disposes it manually since our emit
functions take care of making sure it disposes (and there is
no other way to add source to the underlying MediatorLiveData)
Bug: 140249349
Test: BuildLiveDataTest#raceTest_*
Change-Id: I0b464c242a583da4669af195cf2504e2adc4de40
M lifecycle/lifecycle-livedata-ktx/api/2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/current.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_2.2.0-alpha05.txt
M lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
M lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/CoroutineLiveData.kt
M lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/BuildLiveDataTest.kt
qu...@gmail.com <qu...@gmail.com> #9
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131230928, class android.widget.ListView) with Adapter(class com.students.post.Post_Fragment$Post_listAdapter)]
jb...@google.com <jb...@google.com> #10
The LifecycleOwner
is indeed available from the LifecycleRegistry
so we can add that as part of the message so you know which component it is referring to.
qu...@gmail.com <qu...@gmail.com> #11
jb...@google.com <jb...@google.com>
ap...@google.com <ap...@google.com> #12
Branch: androidx-main
commit e7dfcd2e09ee1dd3589fbd548f50617a8f1c1356
Author: sanura <sanura@google.com>
Date: Thu Oct 13 03:07:32 2022
Update LifecycleRegistry.moveToState() error message
Include the name of the component in the error
message for LifecycleRegistry.moveToState() to
better help developers debug which component is
trying to do an illegal state movement.
RelNote: "`LifecycleRegistry.moveToState()` now
includes more helpful error messaging that informs
developers of the component causing the error."
Test: moveInitializedToDestroyed update
Bug: 244910446
Change-Id: Idf4b23476f809e6c6ff2361d9e864653c90fea2a
M lifecycle/lifecycle-runtime/src/main/java/androidx/lifecycle/LifecycleRegistry.java
M lifecycle/lifecycle-runtime/src/test/java/androidx/lifecycle/LifecycleRegistryTest.java
qu...@gmail.com <qu...@gmail.com> #13
sa...@google.com <sa...@google.com> #14
This has been fixed internally and will be available in Lifecycle 2.6.0-alpha03
il...@google.com <il...@google.com>
re...@livedrive.com <re...@livedrive.com> #15
na...@google.com <na...@google.com> #16
The following release(s) address this bug:
androidx.lifecycle:lifecycle-runtime:2.6.0-alpha03
qu...@gmail.com <qu...@gmail.com> #17
Fatal Exception: java.lang.IllegalStateException: no event down from INITIALIZED in component d{7f1b10e} (0b387363-3c6b-4f7d-af8f-22ebafc87084 id=0x7f0a0302 tag=a::)
il...@google.com <il...@google.com> #18
Re d
is in your app, following the 'You can identify your Fragment' section in the
qu...@gmail.com <qu...@gmail.com> #19
mi...@gmail.com <mi...@gmail.com> #20
androidx.lifecycle:lifecycle-runtime:2.6.0-alpha03
androidx.navigation:navigation-fragment-ktx:2.5.3
androidx.navigation:navigation-ui-ktx:2.5.3
and got crash:
java.lang.RuntimeException: Unable to destroy activity {<package name hidden by me>.MainActivity}: java.lang.IllegalStateException: no event down from INITIALIZED in component androidx.navigation.NavBackStackEntry
with reason:
Caused by: java.lang.IllegalStateException: no event down from INITIALIZED in component androidx.navigation.NavBackStackEntry
(I see that issue is connected with NavBackStackEntry thanks update to :lifecycle-runtime:2.6.0-alpha03)
In my MainActivity there is NavHostFragment with NavController and queue of NavBackStackEntries inside.
When I navigate from Acitivity to some fragment using code below:
Log.i("showSomeFragment","state just before navigate: ${findNavController().currentBackStackEntry?.lifecycle?.currentState}")
findNavController().navigate(
MainNavgraphDirections.actionShowSomeFragment(...)
)
Log shows that NavBackStackEntry's lifecycle's is in state RESUMED, but in target fragment's onCreate (after navigation)
NavBackStackEntry's lifecycle's is in state INITIALIZED
Therefore, when I minimize app being on that fragment - app crashes, because I go from INITIALIZED to DESTROYED state (skipping other states).
When I navigate similarly between fragments (using findNavController().navigate in fragment, not in activity) ->
NavBackStackEntry's lifecycle's state is in state RESUMED in target's fragment onCreate an there is no crash after minimize.
Do I don't understand something/do you have any hints for that, or there is bug in navigation library?
For clarity: Yes, I understand that when we go from INITIALIZED directly to DESTROYED state - error SHOULD be thrown
fr...@gmail.com <fr...@gmail.com> #21
il...@google.com <il...@google.com> #22
Re
pe...@gmail.com <pe...@gmail.com> #23
Fatal Exception: java.lang.RuntimeException: Unable to destroy activity {path to MainActivity}: java.lang.IllegalStateException: no event down from INITIALIZED
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5253)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5282)
at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:44)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2146)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8057)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
il...@google.com <il...@google.com> #24
Re
en...@gmail.com <en...@gmail.com> #25
ah...@gmail.com <ah...@gmail.com> #26
pu...@grabtaxi.com <pu...@grabtaxi.com> #27
pu...@grabtaxi.com <pu...@grabtaxi.com> #28
Hi also having the same problem here, and not able to reproduce it locally, seems from the log that it happened when onBackPressed is triggered. I have tried to put dismiss
inside init
function of my dialog fragment also not able to reproduce it. Is there any thing I can look into?
I'm using
Lifecycle 2.6.1, happened as well in 2.5.1
androidx.lifecycle.LifecycleRegistry.moveToState (LifecycleRegistry.kt:126)
androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent (LifecycleRegistry.kt:119)
androidx.activity.ComponentDialog.onStop (ComponentDialog.kt:87)
androidx.appcompat.app.AppCompatDialog.onStop (AppCompatDialog.java:134)
android.app.Dialog.dismissDialog (Dialog.java:382)
android.app.Dialog.dismiss (Dialog.java:358)
androidx.appcompat.app.AppCompatDialog.dismiss (AppCompatDialog.java:140)
android.app.Dialog.cancel (Dialog.java:1269)
android.app.Dialog.onBackPressed (Dialog.java:684)
androidx.activity.ComponentDialog.onBackPressedDispatcher$lambda$1 (ComponentDialog.kt:94)
androidx.activity.OnBackPressedDispatcher.onBackPressed (OnBackPressedDispatcher.kt:216)
androidx.activity.ComponentDialog.onBackPressed (ComponentDialog.kt:99)
android.app.Dialog.onKeyUp (Dialog.java:661)
android.view.KeyEvent.dispatch (KeyEvent.java:2729)
android.app.Dialog.dispatchKeyEvent (Dialog.java:814)
androidx.appcompat.app.AppCompatDialog.superDispatchKeyEvent (AppCompatDialog.java:209)
androidx.core.view.KeyEventDispatcher.dispatchKeyEvent (KeyEventDispatcher.java:86)
androidx.appcompat.app.AppCompatDialog.dispatchKeyEvent (AppCompatDialog.java:215)
androidx.appcompat.view.WindowCallbackWrapper.dispatchKeyEvent (WindowCallbackWrapper.java:60)
androidx.appcompat.app.AppCompatDelegateImpl$AppCompatWindowCallback.dispatchKeyEvent (AppCompatDelegateImpl.java:3413)
com.android.internal.policy.DecorView.dispatchKeyEvent (DecorView.java:346)
android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent (ViewRootImpl.java:5214)
android.view.ViewRootImpl$ViewPostImeInputStage.onProcess (ViewRootImpl.java:5082)
android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4601)
android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:4654)
android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:4620)
android.view.ViewRootImpl$AsyncInputStage.forward (ViewRootImpl.java:4760)
android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:4628)
android.view.ViewRootImpl$AsyncInputStage.apply (ViewRootImpl.java:4817)
android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4601)
android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:4654)
android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:4620)
android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:4628)
android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4601)
android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:4654)
android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:4620)
android.view.ViewRootImpl$AsyncInputStage.forward (ViewRootImpl.java:4793)
android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent (ViewRootImpl.java:4956)
android.view.inputmethod.InputMethodManager$PendingEvent.run (InputMethodManager.java:2580)
android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback (InputMethodManager.java:2090)
android.view.inputmethod.InputMethodManager.finishedInputEvent (InputMethodManager.java:2081)
android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished (InputMethodManager.java:2557)
android.view.InputEventSender.dispatchInputEventFinished (InputEventSender.java:141)
android.os.MessageQueue.nativePollOnce (MessageQueue.java)
android.os.MessageQueue.next (MessageQueue.java:326)
android.os.Looper.loop (Looper.java:165)
android.app.ActivityThread.main (ActivityThread.java:6861)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:547)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:873)
Description
Fatal Exception: java.lang.IllegalStateException: no event down from INITIALIZED
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:35)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:9)
at androidx.fragment.app.Fragment.performDestroy(Fragment.java:9)
at androidx.fragment.app.FragmentStateManager.destroy(FragmentStateManager.java:147)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:266)
at androidx.fragment.app.SpecialEffectsController$FragmentStateManagerOperation.complete(SpecialEffectsController.java:5)
at androidx.fragment.app.SpecialEffectsController$Operation.cancel(SpecialEffectsController.java:18)
at androidx.fragment.app.SpecialEffectsController.forceCompleteAllOperations(SpecialEffectsController.java:228)
at androidx.fragment.app.SpecialEffectsController.executePendingOperations(SpecialEffectsController.java:14)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:268)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:81)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:21)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:38)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:11)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:4)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:20)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435)
at android.app.Activity.performStart(Activity.java:8231)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3872)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8653)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130
or
Fatal Exception: java.lang.IllegalStateException: no event down from INITIALIZED
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:35)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:9)
at androidx.fragment.app.Fragment.performDestroy(Fragment.java:9)
at androidx.fragment.app.FragmentStateManager.destroy(FragmentStateManager.java:147)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:266)
at androidx.fragment.app.SpecialEffectsController$FragmentStateManagerOperation.complete(SpecialEffectsController.java:5)
at androidx.fragment.app.SpecialEffectsController$Operation.cancel(SpecialEffectsController.java:18)
at androidx.fragment.app.SpecialEffectsController.forceCompleteAllOperations(SpecialEffectsController.java:228)
at androidx.fragment.app.SpecialEffectsController.executePendingOperations(SpecialEffectsController.java:14)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:268)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:81)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:21)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:38)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:11)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:4)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:20)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
at android.app.Activity.performStart(Activity.java:7348)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3138)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
(about 50 different lines with the same stack)
Since it comes 100% from Google code there's nothing we can do about it, unless of course someone could explain what " no event down from INITIALIZED" means...