Skip to content

Lifecycle is disposed after restarting activity #546

@OlehHaidaienko

Description

@OlehHaidaienko

There is an issue with lifecycle when you manually restart activity.
For example, we have a screen that collects flow while visible. When you click on the Restart activity button flow collection resumes and stops forever. TimerManager just emits a value to the flow each second.

class BasicNavigationActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Navigator(screen = LifecycleIssueScreen())
        }
    }
}

internal class LifecycleIssueScreen : Screen {

    @Composable
    override fun Content() {
        val lifecycleOwner = LocalLifecycleOwner.current
        DisposableEffect(Unit) {
            Log.d("Lifecycle_issue", "Screen started")
            onDispose {
                Log.d("Lifecycle_issue", "Screen disposed")
            }
        }
        LaunchedEffect(Unit) {
            TimerManager.currentTime
                .flowWithLifecycle(lifecycleOwner.lifecycle)
                .collect {
                    Log.d("Lifecycle_issue", "Received timer update $it")
                }
        }
        val activity = LocalContext.current as Activity
        Box(modifier = Modifier.fillMaxSize()) {
            Button(
                modifier = Modifier.align(Alignment.Center),
                onClick = {
                    val intent = Intent(activity, BasicNavigationActivity::class.java)
                    activity.startActivity(intent)
                    activity.finish()
                    Log.d("Lifecycle_issue", "Activity restarted")
                }
            ) {
                Text("Restart activity")
            }
        }
    }
}

Image

The root cause of this issue is that the same instance of AndroidScreenLifecycleOwner is used by different activities:

  • App launched
  • First BasicNavigationActivity instance is created
  • AndroidScreenLifecycleOwner is created
  • Restart activity
  • The second BasicNavigationActivity instance is created, it starts displaying content, and since the ScreenLifecycleStore singleton we already have AndroidScreenLifecycleOwnerNavigator starts using the existing AndroidScreenLifecycleOwner
  • First instance of BasicNavigationActivity is stopped → Navigator disposes AndroidScreenLifecycleOwner

When you specify key like override val key: ScreenKey = uniqueScreenKey the issue is gone

Image

Might be related to issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions