Android Activities Lifecycle


What are Activities? (Lifecycle: onCreate, onStart, onResume, onPause, onStop, onDestroy)

Activities are a fundamental building block of Android applications. They represent a single screen with a user interface, where the user can interact with your app. Think of an Activity as a specific task the user can perform, like viewing a list of emails, composing a new email, or viewing the details of a single email.

What is an Activity?

  • An Activity is a component that provides a screen for the user to interact with.
  • Most apps consist of multiple activities, each designed for a specific task. For example, a messaging app might have one activity for viewing conversations, another for composing a new message, and another for viewing contact details.
  • Activities are typically defined by extending the Activity class or one of its subclasses (like AppCompatActivity, which provides backward compatibility for newer features).
  • Each Activity is launched and managed by the Android system.

The Activity Lifecycle:

Activities exist in various states throughout their existence, from when they are first created until they are destroyed. The Android system manages these states and calls specific callback methods on your Activity as its state changes. Understanding these lifecycle methods is crucial for managing resources, saving data, and providing a smooth user experience.

Here are the primary lifecycle callback methods:

onCreate():

  • This is the first callback method called when the Activity is created.
  • It's where you should perform basic application startup logic that should happen only once for the entire life of the activity.
  • Common tasks here include:
    • Setting the user interface using setContentView(R.layout.your_layout).
    • Initializing variables and data structures.
    • Setting up event listeners for UI elements.
  • You must call the superclass implementation of onCreate().
  • It receives a Bundle object containing the activity's previously saved state (if any). This is important for restoring the state when the activity is recreated (e.g., after a configuration change like screen rotation).
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Initialize UI elements, set listeners, etc.
}

onStart():

  • Called when the activity is becoming visible to the user.
  • It follows onCreate() (when the activity is first created) or onRestart() (when the activity is returning from a stopped state).
  • This is a good place to start animations or other processes that should run only when the activity is visible.
override fun onStart() {
    super.onStart()
    // Start animations or other processes
}

onResume():

  • Called when the activity is in the foreground and the user can interact with it.
  • This is the state where the activity spends most of its time when the user is actively using it.
  • It follows onStart() (when the activity is becoming interactive) or onPause() (when the activity is returning from a paused state).
  • This is where you should acquire resources that should only be held when the activity is in the foreground (e.g., camera access, GPS updates).
override fun onResume() {
    super.onResume()
    // Acquire resources (e.g., start camera preview)
}

onPause():

  • Called when the system is about to resume another activity (which will be visible in front of this one).
  • This method is typically used to:
    • Commit unsaved changes to persistent data (e.g., saving user input).
    • Stop animations or other CPU-intensive tasks.
    • Release resources that are only needed while the activity is in the foreground (e.g., release camera).
  • This method should be very brief, as the next activity won't be fully visible until onPause() returns.
  • It's called when the activity is partially obscured or losing focus, but is still visible.
override fun onPause() {
    super.onPause()
    // Save unsaved data, stop animations, release resources
}

onStop():

  • Called when the activity is no longer visible to the user.
  • This can happen when:
    • A new activity covers the entire screen.
    • The user switches to another app.
    • The user navigates back to the home screen.
  • This is where you should release resources that are not needed while the activity is not visible (e.g., unregister broadcast receivers).
  • The system might destroy the activity after onStop() if it needs to reclaim memory.
override fun onStop() {
    super.onStop()
    // Release resources not needed while not visible
}

onDestroy():

  • Called before the activity is destroyed.
  • This is the final callback you receive before the activity is terminated.
  • This can happen because:
    • The user explicitly finishes the activity (e.g., pressing the back button).
    • The system is temporarily destroying the activity to handle a configuration change (like screen rotation).
    • The system is destroying the activity to reclaim memory.
  • You should release all resources that haven't been released by other lifecycle methods.
  • Be cautious about saving data in onDestroy(), as there's no guarantee it will be called in low-memory situations. Use onPause() or onStop() for saving persistent data.
override fun onDestroy() {
    super.onDestroy()
    // Release all remaining resources
}

onRestart():

  • Called when the activity is returning to the foreground after being stopped.
  • It's always followed by onStart() and onResume().
  • This method is not called when the activity is first created.
override fun onRestart() {
    super.onRestart()
    // Code to run when the activity is restarting
}

Saving and Restoring Activity State:

When an activity is temporarily destroyed (e.g., during a configuration change), the system calls onSaveInstanceState() before onStop(). You can override this method to save important data (like the current scroll position or user input) into a Bundle.

When the activity is recreated, the same Bundle is passed to onCreate() and also to onRestoreInstanceState() (which is called after onStart()). You can use this Bundle to restore the activity's previous state.

override fun onSaveInstanceState(outState: Bundle) {
    // Save data to the bundle
    outState.putString("myKey", "myValue")
    super.onSaveInstanceState(outState)
}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    // Restore data from the bundle
    val myValue = savedInstanceState.getString("myKey")
    // Use the restored value
}

Key Takeaways for the Activity Lifecycle:

  • Understand the flow of the lifecycle methods and when each is called.
  • Perform appropriate tasks in each method (initialization in onCreate, resource acquisition/release in onResume/onPause, cleanup in onDestroy).
  • Use onSaveInstanceState and onRestoreInstanceState (or the savedInstanceState Bundle in onCreate) to handle temporary state changes.
  • Be mindful of resource management to avoid leaks and improve performance.
  • The system might destroy your activity at any time after onStop() to free up resources.

Mastering the Activity lifecycle is fundamental to building robust and well-behaved Android applications that can handle various system events and maintain a good user experience.