Android Activity Series Summary (ii)--task and return stack

Source: Internet
Author: User
Tags home screen

Tasks and return stacks

Apps typically contain multiple Activity. Each activity should be designed around specific actions that the user can perform, and can initiate other activity. For example, an e-mail app might have an Activity that displays a list of new messages. When a user selects a message, a new Activity opens to view the message.

An activity can even initiate activity that exists in other apps on the device. For example, if your app wants to send e-mail, you can define Intent to perform a send operation and include some data, such as e-mail addresses and e-mail messages. The system will then open an Activity that declares itself to handle such Intent in other apps. In this case, Intent is sending an e-mail message, so the "compose" activity of the email app (if multiple activity supports the same Intent, the system will let the user select the activity to use). When you send an email, activity resumes, and it looks as if the email activity is part of your app. Even though these two activity may come from different applications, Android will still keep the activity in the same task to maintain this seamless user experience.

A task is a series of activities that interact with the user when a particular job is executed. The Activity is arranged on the stack (that is, the return stack ) in its own order of opening.

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 app doesn't have a task (the app hasn't been used recently), a new task is created, and the app's "primary" activity opens as the root activity in the stack.

When the activity starts another activity, the new activity is pushed to the top of the stack, which becomes the focus. The previous Activity remains on the stack but is in a stopped state. When Activity stops, the system maintains 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 (activity is destroyed), while the previous activity resumes execution (restores the previous state of its UI). The activity in the stack is never rearranged, only pushes in and pops up the stack: pushed into the stack by the current Activity startup, and pops up when the user exits with the return button. Therefore, the return stack runs with a "last in, first out" object structure. Figure 1 shows this behavior visually by displaying the progress between activities and the current return stack for each point in time through the timeline.

Figure 1. Shows how each new Activity in the task adds items to the return stack. When the user presses the back button, the current activity is destroyed and the previous activity resumes execution.

If the user continues to press return, the corresponding activity in the stack pops up to show the previous activity until the user returns to the home screen (or any Activity that is running at the beginning of the task). When all Activity is removed from the stack, the task ceases to exist.

Figure 2. Two tasks: task B receives user interaction in the foreground, while task A waits for recovery in the background.

Figure 3. An Activity is instantiated multiple times.

A task is an organic whole that can be moved to the background when a user starts a new task or goes to the home screen by using the Main Page button. Although all Activity in the task stops in the background, the return stack of the task remains the same, that is, when another task occurs, the task simply loses focus, as shown in 2. The task can then be returned to the foreground and the user will be able to return to the state of departure. For example, suppose that there are three activity in the stack of the current task (task A), that is, there are two activity below the current activity. The user presses the home button First, then launches the new app from the app launcher. When the home screen is displayed, task A enters the background. When the new app starts, it uses its own Activity stack to start a task for the app (Task B). After interacting with the app, the user returns to the home screen again and selects the app that originally launched task A. Task A now appears in the foreground, with all three activity in its stack intact, and activity at the top of the stack resuming execution. At this point, the user can also switch back to task B by going to the home screen and selecting the app icon that launches the task (or by selecting the app's task from the overview screen). This is a multi-tasking example in the Android system.

Note : You can run multiple tasks at the same time in the background. However, if a user runs multiple background tasks at the same time, the system may start destroying background activity to reclaim memory resources, causing the Activity state to be lost. See the section on Activity status below.

Because the activity in the return stack is never rearranged, if the app allows the user to start a specific activity from multiple activity, a new instance of the activity is created and pushed onto the stack (rather than putting any previous instance of the activity on top). Therefore, an activity in an app may be instantiated multiple times (even if the activity comes from a different task), as shown in 3. Therefore, if the user navigates backwards using the back button, the instances are displayed in the order in which each instance of the Activity is opened (each instance has a different UI state). However, you can modify this behavior if you do not want the activity to be instantiated more than once. How to do this will be discussed in the later Management Tasks section.

The default behavior of activity and tasks is summarized as follows:

    • When activity a starts activity B, activity a stops, but the system retains its state (for example, scrolling position and text in the entered form). If the user presses the back button while at Activity B, activity A resumes its state and continues.
    • When a user leaves the task by pressing the Home button, the current Activity stops and its tasks go backstage. The system retains the status of each Activity in the task. If a user later resumes a task by selecting the Launcher icon for the start task, the task appears in the foreground and resumes Activity at the top of the execution stack.
    • If the user presses the back button, the current Activity pops up from the stack and is destroyed. The previous Activity in the stack resumes execution. When the activity is destroyed, the state of the activity is not retained by the system.
    • The Activity can be instantiated more than once, even from other tasks.

Navigation design

For more information on how Android app navigation works, read the navigation guide for Android design.

Save Activity Status

As mentioned above, the default behavior of the system retains its state when activity is stopped. This way, when the user navigates back to the previous Activity, the user interface is the same as when the user leaves. However, when the activity is destroyed and must be rebuilt, you can and should actively use the callback method to preserve the state of the activity.

When a system stops one of your activity (for example, when a new activity starts or a task goes to the foreground), the activity may be completely destroyed if the system needs to reclaim system memory resources. When this happens, information about the activity state is lost. If this happens, the system will still know that the activity is present in the return stack, but when the activity is placed on top of the stack, the system will certainly rebuild the activity (instead of resuming activity). To avoid loss of user work, you should proactively preserve your work by implementing a callback method in your Activity onSaveInstanceState() .

For more information about how to save your activity status, see the activity documentation.

management tasks

The way Android manages tasks and returns stacks (as described above, i.e. putting all of the continuously started Activity into the same task and the "LIFO" stack) is ideal for most applications, and you don't have to worry about how the Activity is associated with a task or how it exists in the return stack. However, you may decide to interrupt normal behavior. Perhaps you want the activity in your app to start a new task at startup (instead of being placed in the current task), or, when you start the activity, you want to move its existing instance up one level (rather than creating a new instance at the top of the return stack), or you want to clear the return stack when the user leaves the task root All other activity other than the activity.

<activity> startActivity() You can do all of these and other actions by using the attributes in the manifest file element and the flags that are passed to the Intent.

In this regard, the main attributes that you can use <activity> include:

    • taskAffinity
    • launchMode
    • allowTaskReparenting
    • clearTaskOnLaunch
    • alwaysRetainTaskState
    • finishOnTaskLaunch

The main Intent flags you can use include:

    • FLAG_ACTIVITY_NEW_TASK
    • FLAG_ACTIVITY_CLEAR_TOP
    • FLAG_ACTIVITY_SINGLE_TOP

In the following sections, you will learn how to use these manifest file properties and the Intent flag to define how activity relates to a task and how activity behaves in the return stack.

In addition, we have separately described the considerations for how to display and manage tasks and Activity in the overview screen. For more information, please see the overview screen. In general, you should allow the system to define how tasks and activities are displayed in the overview screen, and you do not need to modify this behavior.

Note: Most apps must not disrupt activity and the default behavior of tasks: If you determine that your activity has to modify the default behavior, when you use the back button to navigate back to the activity from other activities and tasks, Be careful and be sure to test the availability of the Activity during startup. Make sure the test navigation behavior is likely to conflict with the user's expected behavior.

Defining the startup mode

The startup mode allows you to define how new instances of Activity are associated with the current task. You can define different startup modes in two ways:

    • Working with manifest files

      When you declare an activity in a manifest file, you can specify how the activity should be associated with the task at startup.

    • Using the Intent flag

      startActivity()when called, you can Intent include a flag in to declare how the new Activity (or whether) is associated with the current task.

Therefore, if activity a starts activity B, activity B can define in its manifest file how it should be associated with the current task (if possible), and activity A can also request how activity B should be associated with the current task. If these two activity all define how activity B should be associated with the task, then activity A's request (as defined in Intent) takes precedence over activity B's request (as defined in its manifest file).

Note : Some startup modes that apply to manifest files are not available as Intent flags, and some startup modes that can be used as Intent flags cannot be defined in the manifest file.

Working with manifest files

When you declare an activity in a manifest file, you can use <activity> the attributes of the element launchMode to specify how the activity should be associated with the task.

launchModeproperty to specify instructions about how Activity should be started into a task. launchModeThere are four types of startup modes that you can assign to attributes:

"standard"(default mode)
default. The system creates a new instance of the activity in the task that initiates the activity and transmits the Intent to it. Activity can be instantiated multiple times, and each instance can belong to a different task, and a task can have multiple instances.
"singleTop"
If an instance of the activity already exists at the top of the current task, the system transmits Intent to it by invoking the instance's onNewIntent() method instead of creating a new instance of the activity. Activity can be instantiated multiple times, each of which can belong to a different task, and a task can have multiple instances (provided that the activity at the top of the return stack is not an existing instance of the activity).

For example, suppose the return stack for a task contains root activity A and activity B, C, and D at the top (the stack is a-b-c-d;d at the top). Received a Intent for class D Activity. If D has a default "standard" startup mode, a new instance of the class is started, and the stack becomes a-b-c-d-d. However, if the start mode of D is "singleTop" , then the existing instance of D is onNewIntent() received by Intent because it is at the top of the stack, and the stack is still a-b-c-d. However, if you receive a Intent for Class B Activity, a new instance of B is added to the stack, even if its startup mode is "singleTop" true.

Note : When creating a new instance for an activity, the user can press the back button to return to the previous activity. However, when an existing instance of Activity processes a new Intent, the onNewIntent() user cannot return to the Activity state by pressing the back button until the new Intent arrives.

"singleTask"
The system creates a new task and instantiates the Activity at the bottom of the new task. However, if an instance of the Activity already exists in a separate task, the system transmits Intent to it by invoking the method of the existing instance instead of onNewIntent() creating a new instance. Only one instance of the Activity can exist at a time.

Note : Although the activity starts in a new task, the user presses the back button to return to the previous activity.

"singleInstance".
with the "singleTask" same, only the system will not boot any other Activity into the task that contains the instance. The activity is always the only member of its task, and any activity initiated by the activity is opened in a separate task.

Let's look at another example, the Android browser app declares that the Web browser Activity should always be open in its own task (by <activity> specifying the singleTask startup mode in the Element). This means that if your app issues a Intent that opens an Android browser, its Activity is in a different task than your app. Instead, the system initiates a new task for the browser, or if the browser already has a task running in the background, the task is moved up one level to handle the new Intent.

The user presses the back button to always go to the previous activity, regardless of whether the activity was started in a new task or in the same task as the start activity. However, if you start singleTask an activity that specifies a startup mode, the entire task is transferred to the foreground when an instance of the activity exists in a background task. At this point, the return stack includes all the Activity in the task that was moved up to the top of the stack. Figure 4 shows the situation.

Figure 4. Shows how to add an Activity with a startup mode of "Singletask" to the return stack. If the Activity is already part of a background task that has its own return stack, the entire return stack is also moved up to the top of the current task.

For more information about using the startup mode in a manifest file, see the <activity> element documentation, which discusses launchMode properties and acceptable values in more detail.

Note : The launchMode behavior specified with the property for activity can be overridden by the activity initiation flag that accompanies the Intent, which is discussed later.

Using the Intent flag

When you start the activity, you can modify the startActivity() Default association of activity and its tasks by adding the appropriate flags to the Intent you pass to. Flags that you can use to modify the default behavior include:

FLAG_ACTIVITY_NEW_TASKStart Activity in a new task. If the task is already running for the Activity you are starting, the task will go to the foreground and resume its final state, and the activity will onNewIntent() receive a new Intent in.

As mentioned earlier, this produces "singleTask" launchMode the same behavior as the value.

FLAG_ACTIVITY_SINGLE_TOPIf the activity being started is the current activity (at the top of the return stack), the existing instance receives the onNewIntent() call to the pair instead of creating a new instance of the activity.

As mentioned earlier, this produces "singleTop" launchMode the same behavior as the value.

FLAG_ACTIVITY_CLEAR_TOPIf the activity that is being started is already running in the current task, all the activity at the top of the current task is destroyed, and by onNewIntent() passing this Intent to the instance that the activity has resumed (now at the top), instead of starting a new instance of the activity.

The property that produces this behavior launchMode has no value.

FLAG_ACTIVITY_CLEAR_TOPCommonly FLAG_ACTIVITY_NEW_TASK used in conjunction with. When used together, these flags allow you to find existing Activity in other tasks and place it in a location where you can respond to Intent.

Note : If you specify a startup mode for activity, "standard" the activity is also removed from the stack and a new instance is started in its place to process the incoming Intent. This is because a "standard" new instance will always be created for the new Intent when the startup mode is.

Handling Associations

Association indicates which task the Activity first belongs to. By default, all Activity in the same app is associated with each other. Therefore, by default, all Activity in the same app takes precedence in the same task. However, you can modify the Activity's default association. Activity defined in different apps can share associations, or you can assign different task associations to activity defined in the same app.

You can use <activity> the attributes of an element to taskAffinity Modify the association of any given Activity.

taskAffinityproperty to take a string value that must be different from the <manifest> default package name declared in the element, because the system uses that name to identify the default task association for the app.

In both cases, the association will work:

  • The
  • Intent that initiates Activity contains   flag_activity_new_task   flag.

    By default, new activity is initiated into the activity task of calling   startactivity ()  . It pushes into the same return stack as the caller. However, if passed to   startactivity () Intent contains   flag_activity_new_task   Flag, The system will look for other tasks to store the new Activity. This is usually a new task, but does not make a mandatory requirement. If an existing task has the same association with the new activity, the activity is initiated into the task. Otherwise, a new task will start.

    If this flag causes Activity to start a new task and the user leaves by pressing the home button, you must provide the user with a way to navigate back to the task. Some entities, such as the Notification Manager, always start activity in an external task and never start activity as part of themselves, so they will always be   flag_activity_new_task   into a Intent that is passed to   startactivity ()  . Note that if the Activity can be called by an external entity that can use this flag, the user can return to the started task independently, for example, by using the launcher icon (the root Activity of the task has   Category_launcher  intent Filter; see the Startup Tasks section below).

  • Activity sets its allowTaskReparenting properties to "true" .

    In this case, the activity can move from the task it initiates to the task with which it is associated (if the task appears in the foreground).

    For example, suppose that the Activity that reports the weather condition of the selected city is defined as part of the travel application. It has the same association (default app affinity) as other Activity in the same app, and allows the parent to be reset with this property. When one of your activity initiates the weather forecast activity, it initially belongs to the same task as your activity. However, when a travel app's task appears in the foreground, the forecast Activity is reassigned to the task and displayed in it.

tip : If a file contains multiple apps from a user's perspective, .apk you might want to use taskAffinity attributes to assign different associations to the Activity associated with each app.

Clean up the return stack

If the user leaves the task for a long time, the system clears all activity tasks, except root activity. When the user returns to the task again, only the root Activity is restored. The system does this because, after a long period of time, the user may have abandoned the previous action and returned to the task to begin the new operation.

You can modify this behavior by using the following activity properties:

alwaysRetainTaskState
If this property is set to in the root Activity of the task "true" , the default behavior just described does not occur. Even after a long period of time, the task retains all Activity on its stack.
clearTaskOnLaunch
If you set this property to the root activity of a task "true" , the system clears the stack to only the root activity whenever the user leaves the task and then returns. In other words, it's alwaysRetainTaskState just the opposite. The user will always return to the initial state of the task, even if the task is only a few moments away.
finishOnTaskLaunch
This property is similar to clearTaskOnLaunch , but it works on a single Activity, not the entire task. In addition, it may cause any activity to stop, including root activity. When set to "true" , Activity is still part of the task, but is limited to the current session. If the user leaves and then returns to the task, the task will no longer exist.
Start a task

"android.intent.action.MAIN" "android.intent.category.LAUNCHER" You can set activity as the entry point for a task by providing the activity with a Intent filter for the specified action for the specified category. For example:

<activity >    <intent-filter ... >        <action android:name= "Android.intent.action.MAIN"/>        <category android:name= "Android.intent.category.LAUNCHER"/>    </intent-filter> ...    </ Activity>

Such Intent filters display the activity's icons and labels in the app Launcher, enabling the user to start the activity and return to the created task at any time after launch.

The second feature is important: the user must be able to return to the task using the Activity initiator after leaving the task. Therefore, ACTION_MAIN CATEGORY_LAUNCHER you should only use the two startup modes that Mark activity as "always start task", that is, when the activity has and filters "singleTask" "singleInstance" . For example, let's imagine what happens if a filter is missing: Intent initiates a new task by starting an "singleTask" Activity, and the user takes some time to process the task. The user then presses the Home button. The task is now sent to the background and is not visible. Now, the user cannot return to the task because the task does not appear in the app launcher.

If you do not want the user to be able to return to the activity, for these cases, <activity> set the element finishOnTaskLaunch to "true" (see Cleanup stack).

For more information about how to display and manage tasks and activity in the overview screen, see the Activity's Overview screen (overview screens).

Android Activity Series Summary (ii)--task and return stack

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.