Interview QuestionPractical QuestionFollow-up Questions

Lifecycle Transitions Between Multiple Activities

skydovesJaewoong Eum (skydoves)||10 min read

Lifecycle Transitions Between Multiple Activities

Understanding the lifecycle callback order when navigating between two Activities is essential for managing resources, saving state, and avoiding visual glitches during transitions. The Android system interleaves the lifecycle callbacks of the outgoing and incoming Activities in a specific sequence that ensures the new Activity is ready before the old one fully stops. By the end of this lesson, you will be able to:

  • Trace the exact callback sequence when launching Activity B from Activity A.
  • Explain why Activity A's onStop is called after Activity B's onResume.
  • Describe the callback order when returning from Activity B to Activity A.
  • Identify the role of onRestart in the resume path for a stopped Activity.

Launching Activity B from Activity A

When the user triggers navigation from Activity A to Activity B, the system follows a precise callback order. Activity A does not stop immediately. Instead, the system first prepares Activity B to take over the foreground.

The sequence is:

  1. Activity A: onPause() pauses A's UI and frees resources tied to the visible state.
  2. Activity B: onCreate() initializes B's components and inflates its layout.
  3. Activity B: onStart() makes B visible.
  4. Activity B: onResume() brings B to the foreground and makes it interactive.
  5. Activity A: onStop() stops A after B has fully taken over.

The key detail is that A's onStop is deferred until B is fully resumed. This overlap ensures that the user always sees a fully rendered screen during the transition. If Activity B is translucent or does not fully cover Activity A, then onStop on Activity A is not called at all because A remains partially visible.

You can observe this interleaving by adding log statements to each callback:

class ActivityA : AppCompatActivity() {
    override fun onPause() {
        super.onPause()
        Log.d("Lifecycle", "A: onPause")
    }
    override fun onStop() {
        super.onStop()
        Log.d("Lifecycle", "A: onStop")
    }
    override fun onRestart() {
        super.onRestart()
        Log.d("Lifecycle", "A: onRestart")
    }
}

The logcat output when launching Activity B from A shows that A's onPause appears first, followed by B's onCreate, onStart, and onResume, and finally A's onStop. This ordering is guaranteed by the ActivityManager service in the framework.

Returning from Activity B to Activity A

When the user navigates back from Activity B to Activity A, the reverse sequence occurs:

  1. Activity B: onPause() pauses B as it begins to leave the foreground.
  2. Activity A: onRestart() signals that A is coming back from the stopped state.
  3. Activity A: onStart() makes A visible again.
  4. Activity A: onResume() brings A to the foreground.
  5. Activity B: onStop() stops B after A has resumed.
  6. Activity B: onDestroy() destroys B if the back navigation finishes it.

Activity A goes through onRestart instead of onCreate because it was stopped, not destroyed. The onRestart callback is called exclusively when an Activity transitions from the stopped state back to the started state, distinguishing a resume from a fresh creation.

This interview continues for subscribers

Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.

Become a Sponsor