Android Source Series < nine > in-depth understanding of the launchmodel characteristics of activity from the source point of view

Source: Internet
Author: User
Tags response code home screen

Reprint Please specify source:http://blog.csdn.net/llew2011/article/details/52509515

With the start of the company's new business due to the original APP_A package has been very large, so the above request to develop a app_b, the requirements are app_a and App_b account Universal and two apps can open each other. Account general meaning in the app_a on the login so open app_b is also the default is login state, this implementation is not complicated to introduce; The app is not difficult to open, but in the process of testing found a problem previously not encountered, the phenomenon as shown in the demo:


Operation phenomenon is opened in the App_a app_b, at this time in app_b any operation is no problem, in the case of app_b do not quit if you press the home button to switch to the desktop at this point and then click on the App_a icon to open app_a, found that the interface is APP_ b interface, it was very strange at that time, what causes this phenomenon? At the time it was possible that App_b was running in the App_a task stack, and began to troubleshoot the code, and the code that responds to App_a in App_b is as follows:

<activity    android:name= "COM.LLEW.WB.A"    android:label= "@string/app_name" >    <intent-filter >        <action android:name= "Android.intent.action.MAIN"/>        <category android:name= " Android.intent.category.LAUNCHER "/>    </intent-filter>    <intent-filter>        <action Android:name= "Android.intent.action.VIEW"/>        <category android:name= "Android.intent.category.DEFAULT"/ >        <category android:name= "Android.intent.category.BROWSABLE"/>        <data android:scheme= "Llew"/ >    </intent-filter></activity>
Since we app_a and App_b agreed to open each other in scheme form, the response code looks fine, and then look at the code that opens app_b in app_a as follows:
public void Openapp_b1 () {uri uri = uri.parse ("llew://"); Intent Intent = new Intent (Intent.action_view, Uri); Startactivit Y (intent);}
This is the code that opens our App_b, and it doesn't seem to be a problem, but why does it happen? Then I try to use another way in the Openapp_b, the code is as follows:
public void Openapp_b2 () {Intent Intent = Getpackagemanager (). Getlaunchintentforpackage ("PackageName"); if (null! = Intent) {startactivity (intent);}}

Mode two used before and read this piece of relevant source code, so first think of through Packagemanager to get intent to start our app_b, run the program found the second way is no problem, That is to say in the second kind uses packagemanager obtains the intent certainly is and uses the first way obtains the intent to have the difference, then their difference? Let's not say the conclusion. We then look at the difference between the intent that the running program looks at in the debug mode, respectively:

The intent of mode one is as follows:

The intent of mode two is as follows:

By comparing the intent objects in these two ways, you can find that the intent object in mode two contains the Flg property, and the value of the FLG attribute is exactly the value of intent.flag_activity_new_task, and it is suddenly enlightened. The original way two intent added the Flag_activity_new_task tag, that is, the use of a way to start the app_b when the page is running in the App_a task stack, and through the way two open the App_b page run in the new task stack. In order to prove that the App_b page through mode one is running on the app_a task stack, we can use the adb shell dumpsys activity Activities command to view the activity task stack, as follows:

Then we add the flag_activity_new_task tag in the intent of mode one, and use the adb shell dumpsys ACTIVITY activities command to see the following:

The reason for this is that App_b is running in the App_a task stack, and the workaround is to have app_b run in the new task stack when the app_b is started. The next step is to enter the source code to see the intent object obtained through the Packagemanager where the value of the flag tag bar, in the activity call Getpackagemanager () The Getpackagemanager () method of the indirect parent class contextwrapper is called, and the source code is as follows:

@Overridepublic Packagemanager Getpackagemanager () {///Mbase is a context type and its implementation class is Contextimpl    return Mbase.getpackagemanager ();}
Contextwrapper's Getpackagemanager () method calls the Getpackagemanager () method of the context, and the Mbase implementation class is Contextimpl, So we directly view Contextimpl's Getpackagemanager () method, the source code is as follows:
@Overridepublic Packagemanager Getpackagemanager () {//If Mpackagemanager is not empty, return if    (Mpackagemanager! = null) {        return mpackagemanager;    }    Get Ipackagemanager object by activitythread pm    ipackagemanager pm = Activitythread.getpackagemanager ();    if (PM! = null) {    //Create new Applicationpackagemanager object and return        //doesn ' t matter if we make more than one instance.        return (Mpackagemanager = new Applicationpackagemanager (this, PM));    }    return null;}
Through the source code we know that the Getpackagemanger () method gets the Applicationpackagemanager object, and getting the intent object is the Getlaunchintentforpackage () method that calls the object. The source code is as follows:
@Overridepublic Intent getlaunchintentforpackage (String packagename) {//First see if the package have an INFO activity ; The existence of//such an activity are implied to being the desired front-door for the//overall package (such as if    It has multiple launcher entries).    Intent intenttoresolve = new Intent (intent.action_main);    Intenttoresolve.addcategory (Intent.category_info);    Intenttoresolve.setpackage (PackageName);    list<resolveinfo> ris = queryintentactivities (intenttoresolve, 0);    Otherwise, try to find a main launcher activity. if (RIS = = NULL | | ris.size () <= 0) {//reuse the intent instance intenttoresolve.removecategory (intent.        Category_info);        Intenttoresolve.addcategory (Intent.category_launcher);        Intenttoresolve.setpackage (PackageName);    RIS = queryintentactivities (intenttoresolve, 0);    } if (RIS = = NULL | | ris.size () <= 0) {return null; }//Run here to find the eligible Intent, new Intent Intent Intent = new Intent (intenttoresolve);    Here to intent added we look forward to the Flag_activity_new_task label Intent.setflags (Intent.flag_activity_new_task);    Intent.setclassname (Ris.get (0). Activityinfo.packagename, Ris.get (0). Activityinfo.name); Returns the newly created intent object return intent;}

Through the source we see the Getlaunchintentforpackage () method in Applicationpackagemanager to add flag_activity_new_task tags to the eligible intent, The purpose of this tag is to open a new task stack for the target activity and put the target activity on the bottom of the stack.

Before we start explaining the activity's Launchmode, let's mention the concept of the task and return stack, which is referenced from the official documentation.

  • 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. These Activity is arranged in the stack (the "Return stack") in their respective open order.
    The Device Home screen is the starting point for most tasks. When the user touches the icon in the app Launcher (or the shortcut key 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.

    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.

    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 more than once (even if the activity comes from a different task).
    Note: The background can run multiple tasks at the same time. 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.

Well, the concept of the task and return stack is introduced in a small space, to change the default behavior of the return stack, through the activity of the Launchmode and the flag tag of intent, today we mainly talk about changing the default behavior of the task stack by Launchmode. Android system for Launchmode provides four mechanisms, respectively, is the standard,singletop,singletask,singleinstance, in order to facilitate viewing information on the task stack, here is to say a command:ADB Shell Dumpsys Activity, if you are unfamiliar with the command, please check it and master it yourself. Let's explain each of the Launchmode property values.

  • Standard
    This property is the startup mode for activity by default, In other words, if we do not declare the activity's Launchmode property in Manifest.xml, the system will default to activity configuration, and each time the activity is started, the system will create a new instance of the activity in the current task stack and join the task. The stack.
    "For example: A and B are standard" open in order: A→b→b→b, then the order in the task stack is as follows:

  • Singletop
    1, if the activity's Launchmode attribute is defined as Singletop, if an instance of the activity already exists in the current task stack and is in the top position of the stack, then opening the activity again will not create an instance of the activity. The Onnewintent () method of the activity is recalled. Note: If the activity's Launchmode property is Singletop, the Taskaffinity property is not valid.
    "For example: B is Singletop, others are default" open in order: A→b→b→b, the order in the task stack is as follows:

    2. If the activity's Launchmode attribute is defined as Singletop, if an instance of the activity already exists in the current task stack and is not at the top of the stack, then a new instance of the activity will continue to be created
    "For example: B is Singletop, others are default" open order: A→b→c→b→c→b→c→b

  • Singletask
    1. If the activity's Launchmode attribute is defined as Singletask, if the taskaffinity attribute is not declared at this time (if the taskaffinity attribute is not declared, then the activity will be the package name as its default value)
    "For example: B is Singletask, others are default" open order: A→b→c→d→b

    2. If the Launchmode property of the activity is defined as Singletask, if the Taskaffinity property is declared at this time and the property differs from the package name, the
    "For example: B is Singletask, others are default" open order: A→b

    "For example: B is Singletask, others are default" open order: A→b→c

    "For example: B is Singletask, others are default" open order: A→b→c→d

    "For example: B is Singletask, others are default" open order: A→b→c→d→b

    Based on the results of the operation, we find that when the activity's Launchmode is set to Singletask,singtask, there is only one instance of the activity in the current task stack, if the activity is not on top of the stack, It clears all activity on the activity and callbacks the activity's Onnewintent () method, and the Singletask usage summary is as follows:
    If (a task's affinity = = Activity's affinity) {    if (an instance of this activity is already in this Task) {        This activity starts and clears the top acitivity , by identifying Clear_top     } else {        Create this activity instance in this Task    }}} else {//Task's Affinity property value    Create a new A A task that ffinity the value of the property to    create a new instance of the Activity and put it into the task}
  • SingleInstance
    1, singleinstance slightly better understanding than Singletask, SingleInstance's activity can only be in a new task and this task has and can only have this activity, to raise a chestnut
    "For example: B is singleinstance, others are default" open order: A→b
    "For example: B is singleinstance, others are default" open order: A→b→c→d→c

Based on the above results we have roughly mastered the various characteristics of launchmode, in order to understand the need for the small partners to do their own experiments in various situations to open the activity. This is the end of this article, thanks for watching (*^__^*) ...



"Reference article:"

1, https://developer.android.com/guide/components/tasks-and-back-stack.htm

2, http://www.songzhw.com/2016/08/09/explain-activity-launch-mode-with-examples/



Android Source Series < nine > in-depth understanding of the launchmodel characteristics of activity from the source point of view

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.