Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money

Preface:

As one of the four components of Android, Activity is almost the most touched; Android for Activity management, Android uses Task to manage multiple activities, when we start an application, Android will create a Task for it, and then start the entry of the application Activity;

In the development of the actual project will contain multiple activities, the system uses the task stack to store the created Activity instance, the task stack is a “last in, first out” stack structure. For example, if we start the same Activity multiple times, the system will create multiple instances of the Activity and place them in the task stack one by one. When we press the back key to return, each time one Activity is removed from the stack until the stack is empty.

Without any Activity, the system reclaims the stack;

Therefore, in the Android base, the mode in which an Activity starts is very important;

This article covers the full details of the Activity’s launch mode

A detailed explanation of tasks and task stack

1. Detailed explanation of tasks in Android

① A task is a series of activities that interact with the user while performing a specific job. These activities are placed on the stack (the back stack) in their opening order. The device home screen is the starting point for most tasks. When a user touches an icon in the app launcher (or a shortcut on the home screen), the app’s tasks appear in the foreground. If the application does not have a task (the application has not been used recently), a new task is created and the application’s “main” Activity opens as the root Activity in the stack

② When the current Activity starts another Activity, the new Activity is pushed to the top of the stack and becomes the focus. The previous Activity remains on the stack, but in a stopped state. When an Activity stops, the system keeps the current state of its user interface. When the user presses the “Back” button, the current Activity pops up from the top of the stack (the Activity is destroyed), and the previous Activity resumes (the previous state of its UI). Activities in the stack are never rearranged, only pushed and popped: pushed onto the stack when the current Activity started; The stack pops up when the user exits using the back button. Therefore, the return stack runs as a last-in, first-out object structure

③ The task is an organic whole. When users start a new task or switch to the main screen through the “home” button, they can move to the “background”. Although all activities in the task are stopped in the background, the task’s return stack remains the same, that is, when another task occurs, the task simply loses focus. The task can then be returned to the “foreground” and the user can return to where he left off;

**④ Since the activities in the back stack are never rearranged, ** so if the application allows the user to launch a particular Activity from multiple activities, A new instance of the Activity is created and pushed onto the stack (rather than placing any previous instance of the Activity at the top). Therefore, an Activity in an application may be instantiated multiple times (even if the Activity comes from different tasks);

2. Task stack

(1) When the program is opened, a task stack is created, which is used to store the activities of the current program. All activities belong to a task stack.

(2) A task stack contains a collection of activities, which are ordered to choose which activities to interact with the user: only the activities at the top of the task stack can interact with the user.

(3) The task stack can be moved to the background, and the state of each activity is retained. And list their tasks to the user in an orderly manner without losing their status information.

(4) Exit application: When all activities in all task stacks are removed from the stack, the task stack will be destroyed and the program exits.

(5) Every time the page is opened, an Activity will be added to the task stack, and only when all the activities in the task stack are removed from the stack, the task stack will be destroyed, and the program will exit. This will cause poor user experience, and the program can exit only after clicking back several times.

(6) Each time the page is opened, an Activity will be added to the task stack, which will also cause data redundancy. Too much repeated data will lead to memory overflow (OOM).

To address the shortcomings of the task stack, we introduced the boot mode.

LaunchMode plays an important role in the process of multiple Activity jumps. It determines whether to create new instances of an Activity, reuse existing instances, and share them with other Activity instances in a task.

Activity has a concept of launch modes, which are Standard, singleTop, singleTask, and SingleInstance.

Second, detailed explanation of the startup mode

1, the standard

Standard is the standard startup mode, which is the default when we do not specify an Activity startup mode. In Standard mode, a new instance is created each time an Activity is started, and its onCreate, onStart, and onResume classes are called. The newly created Activity will be placed at the top of the task stack where it started.

For example, if Activity A is on stack S and it starts Activity B(Standard mode), then B will go to stack S where Activity A is.

If you start an Activity in Standard mode without a task stack, such as in a Service, and the new Activity has no task stack to enter, an exception occurs:

Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

FLAG_ACTIVITY_NEW_TASK should be specified for this Activity, which creates a new task stack.

2, singleTop

SingleTop is the top of stack reuse mode. In this mode, if the newly started Activity is already at the top of the task stack, the onPause, onNewIntent, and onResume methods of the Activity are called instead of creating a new instance. If the newly started Activity is not at the top of the stack, it will still be recreated.

For example, the current stack situation is ABCD four activities, A at the bottom of the stack, D at the top of the stack. If the startup mode of D is singleTop, the instance of D will not be created again and the stack will remain ABCD.

If D above is standard startup mode, then the stack will change to ABCDD.

3, singleTask

SingleTask is an in-stack reuse pattern. This is the most complex pattern, as it can involve multiple stacks. When an Activity starts in singleTask mode, such as Activity A, the system first looks to see if the desired task stack exists. If it does not, it creates A new task stack and then adds A to the stack after creating an instance of A. If there is an instance of A in the stack, then the system pushes it to the top of the stack and calls its onNewIntent method. If not, it creates an instance of A and pushes A onto the stack. What do I mean by the task stack required by A? An Activity can specify the name of its desired task stack using the TaskAffinity parameter. By default, all activities require the name of the task stack to be the package name of the application.

If the condition of task stack S1 is ABC, then Activity D is started in singleTask mode and it needs task stack S2. Since there are no instances of S2 and D, the system will first create task stack S2. Then create an instance of D and push it to S2

If the task stack required by D above is S1, then the system directly creates an instance of D and pushes it to S1 because S1 already exists.

If the task stack required by D is S1, but the case in S1 is ADBC, D does not recreate, but instead switches D to the top of the stack and calls the onNewIntent method. What about B and C? They all go off the stack, equivalent to the clearTop effect.

4, singleInstance

SingleInstance is the single-instance mode. This mode is an enhanced version of singleTask, in addition to all the features of singleTask, with the addition that activities in this mode can only be placed in a singleTask stack.

For example, if Activity A is in singleInstance mode, when A is started, the system creates A new task stack, and THEN A is alone in the new task stack. Due to the feature of in-stack reuse, subsequent requests will not create new activities unless the stack is destroyed.

Detailed explanation of startup mode setting

The launch mode can be set in two ways: AndroidMainifest or flag setting via the Intent

1. Set the Activity in the AndroidMainifest configuration

<activity

Android :launchMode=” launchMode”

/ / property

//standard: standard mode

//singleTop: stack top multiplexing mode

//singleTask: stack reuse mode

//singleInstance: singleton mode

// If not set, the Activity starts in standard mode by default

2. Set the flag bit with the Intent

Intent inten = new Intent (ActivityA.this,ActivityB.class);

intent.addFlags(Intent,FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

FLAG_ACTIVITY_SINGLE_TOP: Specifies the startup mode as SingleTop

FLAG_ACTIVITY_NEW_TASK: specifies startup mode as SingleTask.

FLAG_ACTIVITY_CLEAR_TOP: All activities on top of it are removed. SingleTask mode has this effect by default

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS: An Activity with this flag does not appear in the list of historical activities; that is, it cannot be returned to the Activity through the history list

3. The difference between the two

The priority of the Intent setting > the Manifest setting.

FLAG_ACTIVITY_CLEAR_TOP cannot be set in the Manifest mode. The Intent cannot be set SingleInstance.

4. Actual application scenarios of startup mode

1. Application scenario of SingleTask mode

The most common application scenario is to keep our application open with only one instance of an Activity. The most typical example is the Home page shown in the application.

If the user jumps to another page from the home page and wants to return to the home page after several operations, assuming that the user does not use the SingleTask mode and will see the home page several times when clicking back, this is obviously an unreasonable design.

2. Application scenarios of SingleTop mode

If you want to start an Activity of the same type in the current Activity, it is recommended to set the startup mode of this type of Activity to SingleTop, which can reduce the creation of the Activity and save memory!

3. Application scenarios of SingleInstance mode

SingleInstance is a mode to start an activity. It is rarely used for application layer development. I usually use this mode for app periodic reminders. This mode can be tricky to use. Assuming we have activityA, activityB, and activityC, we set activityB to SingleInstance

Case one

ActivityB is on A different stack than activityB and activityC is on A different stack. ActivityB is off. There are several ways to solve this problem. My own method is to restart activityB in the finish method of the closed activity by recording the start of the activity.

The second case

A starts B, then press the home button, and then open the application from the left. A is displayed. This is because when launching the application, we will find the activity display at the top of the stack from the default stack

The third case

When A opens C, C opens B, and B opens A, the result is C, which is caused by two stacks. When B opens A, it actually reaches the stack where A is, and the top of the stack is C, so C is displayed. The solution is to use flag to clear the default stack activity, restart A, or back to C and then start A.

In all three cases, the solution is based on fewer pages, which can cause more problems

To avoid this problem, it is best not to use SingleInstance in the middle tier

If you want C and B to be on the same stack, use taskinfinity and give them the same stack name

(2) onActivityResult cannot be used with SingleInstance because of different stacks

4. Application scenarios of Standard

The default mode for starting an Activity is this. In Standard mode, a new instance is created each time an Activity is started.

Open and close the page normally in the normal application, exit the entire app to close all pages

5. The lifecycle of an Activity is different

The onCreate method of an Activity will not run again if the Activity is reused after SingleTop, SingleTask, or SingleInstance mode is set. The onCreate method is only run when the Activity is first created.

If the display data of the page is not related to the parameters passed by the page jump, you do not need to worry about this problem. If the display data of the page is obtained by getInten(), then the problem will appear: GetInten () gets old data all the time and can’t accept new data when jumping!

Then we need another callback onNewIntent (Intent Intent) method. This method passes in the latest intent so that we can solve the above problem. The suggested approach here is to go to setIntent again. Then we initialize the data and UI again

/** Life cycle callback when reusing an Activity */

@Override

protected void onNewIntent(Intent intent) {

super.onNewIntent(intent);

setIntent(intent);

initData();

initView();

}

6. The actual stack management class

The class that manages the Activity is called in BaseActivity, and then all activities inherit BaseActivity to manage the Activity of the entire project

/ * *

* Activity stack management

* /

public class ActivityStackManager {

private static ActivityStackManager mInstance;

private static Stack mActivityStack;

public static ActivityStackManager getInstance() {

if (null == mInstance) {

mInstance = new ActivityStackManager();

}

return mInstance;

}

private ActivityStackManager() {

mActivityStack = new Stack();

}

/ * *

* into the stack

*

* @param activity

* /

public void addActivity(Activity activity) {

mActivityStack.push(activity);

}

/ * *

* the stack

*

* @param activity

* /

public void removeActivity(Activity activity) {

mActivityStack.remove(activity);

}

/ * *

* Quit completely

* /

public void finishAllActivity() {

Activity activity;

while (! mActivityStack.empty()) {

activity = mActivityStack.pop();

if (activity ! = null) {

activity.finish();

}

}

}

/ * *

* Ends the Activity with the specified class name

*

* @param cls

* /

public void finishActivity(Class<? > cls) {

for (Activity activity : mActivityStack) {

if (activity.getClass().equals(cls)) {

finishActivity(activity);

}

}

}

/ * *

* Finds whether the specified activity exists in the stack

*

* @param cls

* @return

* /

public boolean checkActivity(Class<? > cls) {

for (Activity activity : mActivityStack) {

if (activity.getClass().equals(cls)) {

return true;

}

}

return false;

}

/ * *

* Ends the specified Activity

*

* @param activity

* /

public void finishActivity(Activity activity) {

if (activity ! = null) {

mActivityStack.remove(activity);

activity.finish();

activity = null;

}

}

/ * *

* Finish all activities above the specified activity

*

* @param actCls

* @param isIncludeSelf

* @return

* /

public boolean finishToActivity(Class<? extends Activity> actCls, boolean isIncludeSelf) {

List buf = new ArrayList();

int size = mActivityStack.size();

Activity activity = null;

for (int i = size – 1; i >= 0; i–) {

activity = mActivityStack.get(i);

if (activity.getClass().isAssignableFrom(actCls)) {

for (Activity a : buf) {

a.finish();

}

return true;

} else if (i == size – 1 && isIncludeSelf) {

buf.add(activity);

} else if (i ! = size – 1) {

buf.add(activity);

}

}

return false;

}}

conclusion

1. The above is a summary of the startup mode and application scenario of the Activity. Except for singleTask, which is a little complicated, the rest is easy to understand

2, the start mode is in fact a practical application must be knowledge points, you do not use and only learning is not able to master the essence, only have to really use will become your own;

3, do not understand the message can ask me at any time;