Comments (9)
Here's the config change variant, first bullet above. I believe every frame here is open source, either Androidx or Workflow.
java.lang.IllegalStateException: You can consumeRestoredStateForKey only after super.onCreate of corresponding component
at androidx.savedstate.SavedStateRegistry.consumeRestoredStateForKey(SavedStateRegistry.kt:72)
at androidx.compose.ui.platform.DisposableSaveableStateRegistry_androidKt.DisposableSaveableStateRegistry(DisposableSaveableStateRegistry.android.kt:75)
at androidx.compose.ui.platform.DisposableSaveableStateRegistry_androidKt.DisposableSaveableStateRegistry(DisposableSaveableStateRegistry.android.kt:54)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:105)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$3.invoke(Wrapper.android.kt:157)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$3.invoke(Wrapper.android.kt:156)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:156)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:140)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:78)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3248)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3238)
at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown:1)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3238)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3173)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:587)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:950)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:519)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:140)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:1060)
at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:131)
at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:182)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151)
at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.java:121)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.updateLifecycle$wf1_core_android(WorkflowLifecycleOwner.kt:203)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.updateLifecycle$wf1_core_android$default(WorkflowLifecycleOwner.kt:193)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.onStateChanged(WorkflowLifecycleOwner.kt:175)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151)
at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.java:121)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.updateLifecycle$wf1_core_android(WorkflowLifecycleOwner.kt:203)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.updateLifecycle$wf1_core_android$default(WorkflowLifecycleOwner.kt:193)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.onStateChanged(WorkflowLifecycleOwner.kt:175)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151)
at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.java:121)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.updateLifecycle$wf1_core_android(WorkflowLifecycleOwner.kt:203)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.updateLifecycle$wf1_core_android$default(WorkflowLifecycleOwner.kt:193)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.onStateChanged(WorkflowLifecycleOwner.kt:175)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:202)
at com.squareup.workflow1.ui.androidx.RealWorkflowLifecycleOwner.onViewAttachedToWindow(WorkflowLifecycleOwner.kt:161)
at android.view.View.dispatchAttachedToWindow(View.java:15544)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2916)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2923)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1530)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1258)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6351)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Method.java:-2)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
from workflow-kotlin.
Fixed one variant (not the one whose stack trace is above) by eliminating a spot where we were driving a WorkflowViewStub
via an RxJava Observable
stream. Replaced that with direct calls to ScreenViewHolder.show
, which also eliminates one use of WorkflowLifecycleOwner
.
Absolutely no idea why that fixed anything, but at least we're getting an idea of what to wiggle.
from workflow-kotlin.
Fixed one variant
False.
from workflow-kotlin.
Found this comment in DisposableSaveableStateRegistry
, while debugging where the SaveableStateRegistry:-1
key comes from (the key that causes the exception to be thrown from SavedStateRegistry
, and thank you androidx team for a characteristically useless exception message):
// The view id of AbstractComposeView is used as a key for SavedStateRegistryOwner. If there
// are multiple AbstractComposeViews in the same Activity/Fragment with the same id(or with
// no id) this means only the first view will restore its state. There is also an internal
// mechanism to provide such id not as an Int to avoid ids collisions via view's tag. This
// api is currently internal to compose:ui, we will see in the future if we need to make a
// new public api for that use case.
Sure enough, if I provide generated (and therefore useless) ids for each ComposeView
we instantiate, the crash goes away. This also breaks view persistence for Compose, but we're practically there already.
from workflow-kotlin.
Do we need to introduce a WorkflowSavedStateRegistryAggregator
at every ComposeView
boundary?
from workflow-kotlin.
Non-conflicting id's "fix" only worked once. How?
from workflow-kotlin.
More likely I'm punchy and missed a step in the repro recipe.
from workflow-kotlin.
We've found other, simpler recipes. AndroidView
is not in the chain, dialog windows always are. Current theory is that on config change, dialog contents are getting restored before the activity is resumed -- maybe some kind of surprising depth first behavior where android lifecycle resumes children before parents?
Going to try making dialogs use the activity context as the parent lifecycle owner, instead of the owner of the BodyAndOverlaysContainer
. That does seem very wrong, and prone to failing to tear down dialogs when their container vanishes, but let's see what happens.
from workflow-kotlin.
Possible fix! #1003. Running it against our internal test suite now.
from workflow-kotlin.
Related Issues (20)
- Rework `ScreenViewFactoryFinder` s.t. it prefers `ViewRegistry` entries for the built in types too
- Consider open sourcing our wrappers for onbackpresseddispatcher HOT 2
- Remove mobile.dev integration
- Remove references to 'tick' from runtime in the tests.
- Consider providing access to the CoroutineScope in `initialState` HOT 1
- Side effects / Workers / LifecycleWorker methods not called if rendered/not rendered without ever yielding dispatch HOT 8
- `ComponentDialog.asDialogHolderWithContent` should provide decor view as container
- UI Test shards are flaky, perhaps interfering with each other? HOT 2
- Introduce `BackStackScreen.flatten()`
- Un-deprecate runningWorker for LifecycleWorker HOT 2
- SessionWorkflow throws when trying to unit test it with RenderTester#testRender
- Deprecate one/disambiguate between launchForTestingFromStart/StateWith and headlessIntegrationTest HOT 1
- Consider removing `ViewEnvironment` parameter from `RenderWorkflowIn`
- Offer config option to skip rendering when new state == old HOT 3
- Showing Overlay causes crash when using AnimatedContent to animate screens HOT 2
- RenderContext passed into StatefulWorkflow#render is new instance every time HOT 3
- Consider version of `initialState` that provides a `CoroutineScope` identical to the `WorkflowNode`'s HOT 9
- Deprecate `runningWorker` and add `@ReplaceWith` for `runningSideEffect` alternative
- Remove JMH Benchmarks
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from workflow-kotlin.