Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[StackNavigation] InstanceKeeper instances of component are destroyed earlier than component itself, leading to access to released resources. #383

Closed
HeroBrine1st opened this issue May 7, 2023 · 2 comments · Fixed by #388
Labels
bug Something isn't working

Comments

@HeroBrine1st
Copy link

HeroBrine1st commented May 7, 2023

Hello. I found that in StackNavigation Instances of component are destroyed first, and then lifecycle of component is going pause-stop-destroy. I found that when implemented pause of video play on pause of component (which IMO is good as video is not playing in background) and also "releasing" (i.e. destroying with release of resources like threads etc) ExoPlayer in onDestroy method of Instance.

So, when I navigate back from screen with video I see this warning in logs:

Handler (android.os.Handler) {c3b8656} sending message to a Handler on a dead thread
java.lang.IllegalStateException: Handler (android.os.Handler) {c3b8656} sending message to a Handler on a dead thread

That is a clear signal that Instance::onDestroy is called first, and then Lifecycle.Callbacks::onPause is called (because stack trace leads to onPause).

I also found the source of this exception in Decompose code. Lines 189 and 190 are in wrong order and that is the problem. I think reproductions steps are not needed as the error is clear from code below:

private fun destroyOldItems(
newConfigurations: Set<C>,
oldItems: Collection<ChildItem<C, T>>,
) {
for (item in oldItems) {
val child = item as? Created ?: continue
if (item.configuration !in newConfigurations) {
child.backHandler.stop()
child.instanceKeeperDispatcher.destroy()
child.lifecycleRegistry.destroy()
}
}
}

Why this should not happen: because instances of classes should be destroyed only when there are no external links to them, i.e. noone can access already destroyed classes or releases resources. On android, ViewModel is destroyed later than Activity, for example.

Btw, I use 2.0.0-alpha-01 version, and tried with 2.0.0-alpha-02 - the error is still here. Artifacts used: decompose and extensions-compose-jetpack on Android 13 (Pixel Experience).

@HeroBrine1st HeroBrine1st changed the title [StackNavigation] Instances of component are destroyed earlier than component itself, leading to access of releases resources. [StackNavigation] Instances of component are destroyed earlier than component itself, leading to access of released resources. May 7, 2023
@HeroBrine1st HeroBrine1st changed the title [StackNavigation] Instances of component are destroyed earlier than component itself, leading to access of released resources. [StackNavigation] InstanceKeeper instances of component are destroyed earlier than component itself, leading to access to released resources. May 7, 2023
@arkivanov
Copy link
Owner

arkivanov commented May 7, 2023

Hello and thanks for reporting! Indeed it looks like a bug. I will investigate it further and provide updates here.

@arkivanov arkivanov added investigate Something might be broken and needs to be investigated bug Something isn't working and removed investigate Something might be broken and needs to be investigated labels May 7, 2023
@arkivanov
Copy link
Owner

Thanks again for reporting, will be fixed in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants