Scroll to top

In my previous post, you learned that Intents let us send messages from one Android component to another. Well, one very important kind of component is an Activity.

Activities are a fundamental part of Android app development. And it's impossible to understand Activities without also understanding their lifecycles. In this post, you'll learn all about the Activity lifecycle.

An Activity is a single screen in Android. It is like a window in a desktop app or a Frame in a Java program. An Activity allows you to place all your UI components or widgets together on the screen.

It's important to understand that an Activity has a lifecycle: that is to say that it can be in one of several different states, depending on what is happening with the app and with the user interaction.

Lifecycle Methods

Let's look more closely at the lifecycle of an Android Activity. Each time the Activity state changes, one of the following lifecycle methods will be called on the Activity class.

onCreate(): This is called when the Activity is first initialized. You need to implement this method in order to do any initialization specific to your Activity.

onStart(): This is called the first time that the Activity is about to become visible to the user, as the Activity prepares to come to the foreground and become interactive. Once this callback finishes, the onResume() method will be called.

onResume(): When the Activity goes into this state, it begins to interact with the user. The Activity continues in this state till something happens to take focus from the app or Activity (such as an incoming call). When this happens, the onPause() method will be called.

onPause(): This method is used to pause operations that should not happen when the Activity is in paused state. A call to this method indicates that the user is leaving the app. For example, in a music player app, an incoming call will cause the app to transition into a paused state. This should mute or pause the currently playing music. When the user returns to the app, the onResume() method will be called.

onStop(): This method is called when the Activity is no longer visible in the app. It can happen, for example, when another Activity has been loaded and is taking the full screen of the device. When this method is called, the Activity is said to be in a stopped state. In this state, the system either calls the onRestart() to bring back interactivity with Activity or it calls the onDestroy() method to destroy the Activity.

onDestroy(): This gets called before the Activity is destroyed. The system calls this method when a user terminates the Activity, or because the system is temporarily destroying the process that contains the Activity to save space. Be sure to free up any resources your Activity has created in this method, or else your app will have a memory leak!

onRestart(): This gets called when an Activity restarts after it had been stopped.

One easy way to see when different lifecycle events are triggered is to implement a skeletal version of these callbacks that simply creates a Toast like this:

1
@Override
2
protected void onCreate(Bundle savedInstanceState) {
3
    super.onCreate(savedInstanceState);
4
    
5
    // Do some other initialization

6
    
7
    Toast.makeText(this, "Creating MainActivity", Toast.LENGTH_SHORT).show();
8
}
9
        
10
@Override
11
protected void onStart() {
12
    Toast.makeText(this, "Starting MainActivity", Toast.LENGTH_SHORT).show();
13
    super.onStart();
14
}
15
16
@Override
17
protected void onResume() {
18
    Toast.makeText(this, "Resuming MainActivity", Toast.LENGTH_SHORT).show();
19
    super.onResume();
20
}
21
22
@Override
23
protected void onPause() {
24
    Toast.makeText(this, "Pausing MainActivity", Toast.LENGTH_SHORT).show();
25
    super.onPause();
26
}
27
28
@Override
29
protected void onStop() {
30
    Toast.makeText(this, "Stopping MainActivity", Toast.LENGTH_SHORT).show();
31
    super.onStop();
32
}
33
34
@Override
35
protected void onDestroy() {
36
    Toast.makeText(this, "Destroying MainActivity", Toast.LENGTH_SHORT).show();
37
    super.onDestroy();
38
}

Starting an Activity

Most user interactions with an app cause the active Activity to be changed. So an app transitions between Activities many times during its lifetime.

It's necessary to link Activities together when one Activity needs to start another Activity. To start an Activity, you either use startActivity() or startActivityForResult(). You have to pass an Intent in either case.

Starting an Activity With No Expected Result

startActivity() is used if the newly started Activity does not need to return a result.

The following code snippet shows how to start another Activity using this method:

1
Intent intent = new Intent(this, SecondActivity.class);
2
startActivity(intent);

You can also perform actions such as passing data from one Activity to another. In this case, your current Activity (the calling Activity) wants to pass data a target Activity. This is where Intents come in handy. To learn about using Intents to start an Activity, check out my previous article.

Starting an Activity With a Result

startActivityForResult() is used to start another Activity and expects to get data back from the newly started Activity. In other words, use this when you want to get a result from the target Activity back to the calling Activity, e.g. if the target Activity is collecting some user information in a modal dialog.

You receive the result from the Activity in the onActivityResult(int requestCode, int resultCode, Intent data) method. The result will be returned as an Intent.

Example of Starting an Activity

Here is an example to show how starting an Activity works.

First, you create your MainActivity with your onCreate() method, a layout file, and a request code.

1
  public class MainActivity extends Activity {
2
3
      // Unique request code for each use case 

4
      private static final int REQUEST_CODE_EXAMPLE = 0x9345; 
5
6
      @Override
7
      protected void onCreate(Bundle savedInstanceState) {
8
          super.onCreate(savedInstanceState);
9
          setContentView(R.layout.activity_main);
10
      }
11
    
12
  }

In your onCreate() method, you'll create a new instance of an intent to start your second Activity.

When you're ready to start that Activity, say in response to a button click, you'll call startActivityForResult(), which will pass the newly created intent and the request code.

1
  // Create a new instance of Intent to start SecondActivity

2
  final Intent intent = new Intent(this, SecondActivity.class);
3
4
  // This starts SecondActivity with the request code

5
  startActivityForResult(intent, REQUEST_CODE_EXAMPLE);

Still, in your MainActivity, you need to handle Activity result events. You do this by implementing the onActivityResult() method. This is how you will receive the result from the other Activity.

Here's how it should look:

1
    // onActivityResult only get called 

2
    // when the other Activity previously started using startActivityForResult

3
    @Override
4
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
5
        super.onActivityResult(requestCode, resultCode, data);
6
7
        // First we need to check if the requestCode matches the one we used.

8
        if(requestCode == REQUEST_CODE_EXAMPLE) {
9
10
            // The resultCode is set by the SecondActivity

11
            // By convention RESULT_OK means that whatever

12
            // SecondActivity did was executed successfully

13
            if(resultCode == Activity.RESULT_OK) {
14
                // Get the result from the returned Intent

15
                final String result = data.getStringExtra(SecondActivity.EXTRA_DATA);
16
17
                // Use the data - in this case, display it in a Toast.

18
                Toast.makeText(this, "Result: " + result, Toast.LENGTH_LONG).show();
19
            } else {
20
                // setResult wasn't successfully executed by SecondActivity 

21
                // Due to some error or flow of control. No data to retrieve.

22
            }
23
        }
24
    }

Now go ahead and create your SecondActivity. It should look something like the code below.

1
  @Override
2
    protected void onCreate(Bundle savedInstanceState) {
3
        super.onCreate(savedInstanceState);
4
        setContentView(R.layout.activity_detail);
5
6
        final Button button = (Button) findViewById(R.id.button);
7
        // When this button is clicked we want to return a result

8
        button.setOnClickListener(new View.OnClickListener() {
9
            @Override
10
            public void onClick(View view) {
11
                // Create a new Intent object as container for the result

12
                final Intent data = new Intent();
13
14
                // Add the required data to be returned to the MainActivity

15
                data.putExtra(EXTRA_DATA, "Some interesting data!");
16
                
17
                // Set the resultCode as Activity.RESULT_OK to 

18
                // indicate a success and attach the Intent

19
                // which contains our result data

20
                setResult(Activity.RESULT_OK, data); 
21
22
                // With finish() we close the SecondActivity to 

23
                // return back to MainActivity

24
                finish();
25
            }
26
        });
27
    }

Terminating an Activity

Before an Activity terminates, the corresponding lifecycle methods will be called.

The onPause() method should stop all listeners and UI updates. The onStop() method should save the application data. Finally, the onDestroy() method will free up any resources that the Activity has allocated.

When the user switches back to an app that has been terminated by the system, the onResume() method is called. Based on saved data, it can re-register listeners and trigger UI updates.

Activity Instance State

An Activity needs a way to keep valuable state and user data that it has obtained. This data might be obtained from user input or created while the Activity was not on-screen.

Sometimes, your users will themselves exit an activity intentionally by pressing the back button. In such cases, they expect the instance data to be destroyed, and you don't have to write any extra code to save the UI data to restore the activity to its previous state. However, this is not always the case.

For example, a change of device orientation can cause an Activity to be destroyed and recreated. In such a scenario, you need to make sure to save all Activity state before it is destroyed and reload it again when it is recreated. Otherwise, any data your Activity has at that time can be completely lost.

To save Activity state, you can override the onSaveInstanceState() method. This method is passed a Bundle object as a parameter. A bundle can contain strings, primitive data types, or objects. In this method, simply add any important state data to the bundle. This bundle will be returned to the Activity later so you can restore the Activity state.

The system itself also uses the Bundle object to save the instance state. However, it is limited to keeping track of the information related to a variety of View objects, such as the text that you entered into an EditText widget. When an activity instance is destroyed and recreated, the system will use this saved data to restore the state of the activity. You will still be responsible for saving and restoring any extra information that you want to preserve across different activity instances. 

To extract the saved state from the bundle and restore it, implement the onRestoreInstanceState() method. This callback is invoked between the onStart() and onResume() lifecycle methods.

We will look deeper into Activity instance state in a future article.

Navigation Between Activities

There are a few different ways in which you can navigate between activities on your Android device. The sequence in which different callback methods are triggered will ultimately depend on the navigation method.

One Activity Starts Another

Unless the app you are developing is very simple, you will likely have multiple activities within the same app. Some functionality in your app might require user navigation from one activity to another. Let's see the sequence of callback functions that happens during navigation between different activities.

We will use the app we developed in the tutorial about Intents in Android to discuss the sequence of events here. The MainActivity in the app has a Submit button that takes users to ShowActivity.

Let's say a user enters some information in MainActivity and then clicks the Submit button. This will trigger the callback to onPause() inside MainActivity. The click on the Submit button is supposed to take us to the ShowActivity. Therefore, the calls to onCreate(), onStart(), and onResume() are triggered for ShowActivity just after that.

Our MainActivity is no longer visible on the screen now. Therefore, the onStop() callback for MainActivity is triggered next.

New Activity or Dialog Appears on Screen

A variety of events can bring a new activity to the foreground, like the user receiving a call or a quick gesture shortcut. The callback sequence for your activity in this case will depend on whether the new activity fully or partially covered your activity.

When covered partially, your activity will trigger a callback to onPause(). The activity will then trigger a call to onResume() when it comes back to the foreground.

When covered completely, your activity will quickly trigger the callbacks to onPause() and onStop() one after the other. If your activity comes back to the foreground, the callbacks to onRestart(), onStart(), and onResume() will be triggered as long as the same instance of the activity came to the foreground. If a new instance of the activity is created, only the callbacks to onStart() and onResume() will be triggered.

Conclusion

After following this post, you should now have a good understanding of how an Activity lifecycle works. And you've learned that there are two ways to start an Activity, as well as getting some pointers to how instance state is handled in the Activity lifecycle.

Thanks for reading, and while you're here, check out some of our other posts on coding Android apps.

This post has been updated with contributions from Nitish Kumar. Nitish is a web developer with experience in creating eCommerce websites on various platforms. He spends his free time working on personal projects that make his everyday life easier or taking long evening walks with friends.

Thumbnail generated by Open AI DALL-E.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.