Typically, Android creates a task stack as soon as each application is started, and the ID of the task stack is self-increasing. When minimized, the application actually runs in the background and the task stack remains.

  • Standard Startup mode: In this mode, each new Activity started is placed at the top of the task stack and does not reuse
  • SingleTop startup mode: In this mode, if an Activity already exists at the top of the stack, the system will not create it again. Instead, the system will reuse the existing Activity only from the top of the stack
  • SingleTask startup mode: In this mode, only one instance of an Activity is required to exist in the task stack. If the Activity to be started is already in the task stack, the system directly reuses the existing Activity, empties all stack references on the Activity, and reuses all existing activities
  • SingleInstance startup mode: In this mode, the system creates a single task stack, which is unique in the entire mobile OS memory. For example, when making a phone call, the call interface is globally unique

Then there is the Activity life cycle, saving the state of information when forced to exit, listening for the back key, passing data between activities, and so on.

There are four launch modes for an Activity

There are four launch modes for an Activity:

1. Standard Startup mode

In this mode, every new Activity that is started is placed at the top of the task stack and there is no reuse.

2. SingleTop startup mode

In this mode, if an Activity already exists at the top of the stack, the system will not create it again. Instead, it will reuse only the Activity at the top of the stack.

3. SingleTask startup mode

In this mode, only one instance of an Activity is required to exist in the task stack. If the Activity to be started is already in the task stack, the system directly reuses the existing Activity, empties all stack references on the Activity, and reuses all existing activities.

4. SingleInstance startup mode

In this mode, the system creates a single task stack that is unique within the entire operating system memory. For example, when making a phone call, the call interface is globally unique.

Activity Lifecycle

Activity is one of the most basic and most commonly used four components in Android components, and it is also one of the components we touch most in the development process, so it is essential to understand the life cycle of Activity, and the correct understanding and application, the following is to introduce the Activity life cycle.

In AndroidStudio, you can use logt to quickly generate tags. Logd, logv, logi, and loge are shortcut keys for printing different levels of logs.

OnCreate () : called when the Activity is first created. This method (if any) provides you with a bundle containing frozen state information for the previous activity.

OnStart () : called when the Activity is displayed in front of the user. OnResume () is followed if the activity appears in the foreground, and onStop() if the activity is hidden.

OnResume () : called when the Activity is about to start interacting with the user. At this point in time your activity will be at the top of the activity stack, and user input will access it.

OnPause () : When the system is about to resume a previous activity. This is typically used to commit unstored changes to persistent data, stop animations, and consume CPU. Implementing this method must be particularly quick, because the next activity will not resume until the method returns. OnResume () is next called if the activity will return to the foreground, and onStop() if it is hidden from the user.

OnStop () : Called when another Activity is resumed and completely overwritten, and the Activity is not displayed to the user. This happens when a new activity will be started, an exited activity will be resumed, or the activity will be destroyed. Call onRestart() if the activity is going to resume interaction with the user, and onDestory() if the activity is going to be destroyed.

OnDestory () : The last method to be called when the Activity is destroyed. This method will happen because the activity will end (call finish() in the activity, or the system will destroy the instance temporarily to save space. You can use the isFinishing() method to distinguish between these two scenarios.

From opening the app to MainActivity and then back to exit the app:

Now that SecondActivity is open, what about the life cycle of MainActivity and SecondActivity?

First, MainActivity enters the pause state, then SecondActivity enters the initialization phase (onCreate, onStart, onResume). While SecondActivity is fully displayed and waiting for the user to do something, MainActivity only enters the onStop() method, so onStop is only done when the Activity is no longer displayed. OnRestart () -> onStart() -> onResume() -> onPause () -> onResume() -> onPause () Also wait for MainActivity’s onResme execution to complete before gradually destroying.

What about DialogActivity instead?

MainActivity is not completely blocked by DialogActivity, so it does not enter onStop(), but only onPause. MainActivity executes the onResume method directly after exiting DialogActivity. So if the Activity is not completely blocked, it will enter the pause state. When the pause resumes, onResume is executed directly.

Opening the Dialog box directly does not relate to the Activity life cycle, so no logs about the Activity life cycle are printed.

Save the status of the system exit Activity

If the system breaks the Activity due to system constraints (rather than normal application behavior, such as running out of memory), the system remembers that the actual Activity instance existed even after it has disappeared, so that if the user navigates back to it, The system creates a new instance of the Activity and uses a set of saved data to describe the state of the Activity when it is destroyed. The saved data that the system uses to restore the previous state is called “instance state” and is a collection of key-value pairs stored in the Bundle object.

Overwrite the following method in the Activity. The following example writes a String key-value pair when the program exits unexpectedly:

@Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putString("name", "Tim"); Log.i(TAG, "onSaveInstanceState: Success!" ); }Copy the code

Because onCreate() calls this method to see if the system is creating a new Activity instance or recreating a previous one, you must Bundle to check that the state is empty before attempting to read. If it is empty, the system is creating a new instance of the Activity, rather than restoring the previously destroyed instance:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.i(TAG, "onCreate: ");

    if(savedInstanceState != null){
        String name = savedInstanceState.getString("name");
        // TODO ...
    }
}
Copy the code

onBackPressed()

Overwrite onBackPressed to listen for the user to press the return key:

@Override public void onBackPressed() { super.onBackPressed(); Log. I (TAG, "onBackPressed: user presses the return key "); }Copy the code

Based on this method, we can easily implement the function of prompting the program to exit or not by pressing the back key:

@Override public void onBackPressed() { //super.onBackPressed(); Log. I (TAG, "onBackPressed: user presses the return key "); AlertDialog.Builder builder = new AlertDialog.Builder(this); Builder. SetTitle (" tip "); Builder.setmessage (" Are you sure you want to exit the program?" ); Builder. SetPositiveButton (" sure, "(dialog, which) - > {super. OnBackPressed (); }); Builder. SetNegativeButton (" cancel ", null); builder.show(); }Copy the code

Data transfer between activities

Intents deliver basic data

Click event to open a new Activity in MainActivity:

public void newActivity(View view) {
    Intent intent = new Intent(this, SecondActivity.class);
    intent.putExtra("appName", getString(R.string.app_name));
    intent.putExtra("strArray", new String[]{"A", "B", "C"});
    startActivity(intent);
}
Copy the code

Receiving data in SecondActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    Log.i(TAG, "onCreate: ");
    Intent intent = getIntent();
    String[] arrays = intent.getStringArrayExtra("strArray");
    String appName = intent.getStringExtra("appName");
    Log.i(TAG, "onCreate: arrays = " + Arrays.toString(arrays));
    Log.i(TAG, "onCreate: appName = " + appName);
}
Copy the code

The Intent to pass the Bundle

Click event to open a new Activity in MainActivity:

public void newActivity(View view) {
    Intent intent = new Intent(this, SecondActivity.class);
    Bundle bundle = new Bundle();
    bundle.putString("appName", getString(R.string.app_name));
    bundle.putStringArray("strArray", new String[]{"A", "B", "C"});
    intent.putExtra("data", bundle);
    startActivity(intent);
}
Copy the code

Receiving data in SecondActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    Log.i(TAG, "onCreate: ");
    Intent intent = getIntent();
    Bundle bundle = intent.getBundleExtra("data");
    if (bundle != null) {
        String[] arrays = bundle.getStringArray("strArray");
        String appName = bundle.getString("appName");
        Log.i(TAG, "onCreate: arrays = " + Arrays.toString(arrays));
        Log.i(TAG, "onCreate: appName = " + appName);
    }
}
Copy the code

Intent delivery object

Pass a simple object like this:

public class User implements Serializable {
    public String name;
    public int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }    
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }    
    // getter and setter..
}
Copy the code

Click event to open a new Activity in MainActivity:

public void newActivity(View view) {
    Intent intent = new Intent(this, SecondActivity.class);
    intent.putExtra("user", new User("Tim", 18));
    startActivity(intent);
}
Copy the code

Receiving data in SecondActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    Log.i(TAG, "onCreate: ");
    Intent intent = getIntent();
    Serializable user = intent.getSerializableExtra("user");
    Log.i(TAG, "onCreate: user = " + user);
}
Copy the code

Activity Data is sent back

The examples above are all from MainActivity to SecondActivity, but SecondActivity does not send back data. Here is an example of an Activity data return:

First, the button click event is written as:

public void newActivity(View view) { Intent intent = new Intent(this, SecondActivity.class); RequestCode startActivityForResult(intent, 666); }Copy the code

You also need to override the onActivityResult() method in MainActivity

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); If (requestCode == 666 && resultCode == RESULT_OK){setTitle("SecondActivity returns successfully "); if (data ! = null) { Bundle resultData = data.getBundleExtra("resultData"); String appName = resultData.getString("appName"); Log.i(TAG, "onActivityResult: appName = " + appName); }}}Copy the code

In SecondActivity, the button click event is written as :(simply upload data + close the current Activity)

public void backMainActivity(View view) {
    Intent intent = new Intent();
    Bundle bundle = new Bundle();
    bundle.putString("appName", getString(R.string.app_name));
    intent.putExtra("resultData", bundle);
    setResult(RESULT_OK, intent);
    finish();
}
Copy the code