Android -- taskAffinity attribute, androidaffinity
The ownership of the Activity, that is, the adsorption relationship between the Activity and the Task in which the Activity should be located. We know that in general, in the same application, all started activities are in the same Task, and they spend their own lifecycles in the Task. These activities are a good example for the end-to-end.
So Why will the Activity we created enter this Task? Will they be transferred to other tasks? If it is transferred to another Task, what Task will it go?
The key to solving these problems lies in the taskAffinity attribute of each Activity.
Each Activity has the taskAffinity attribute, which specifies the Task it wants to enter. If an Activity does not explicitly specify the taskAffinity of the Activity, its attribute is equal to the taskAffinity specified by the Application. If the Application does not, the value of taskAffinity is equal to the package name. Task also has its own affinity attribute. Its value is equal to the taskAffinity value of its root Activity.
At the beginning, the created Activity will be in the Task where it is created, and most of the activities have passed its entire life here. However, in some cases, the created Activity will be allocated to other tasks, and some may even be transferred after being originally in a Task. First, let's analyze the two situations described in the android document.
First case. If the allowTaskReparenting of the Activity is set to true, it enters the background. When a Task with the same affinity as the Activity enters the foreground, it re-hosts and enters the foreground task.
Let's verify this situation.
Application Activity taskAffinity allowTaskReparenting
Application1 Activity1 com. winuxxan. affinity true
Application2 Activity2 com. winuxxan. affinity false
We create two projects, application1 and application2, which contain Activity1 and Activity2 respectively. Their taskAffinity is the same, and the allowTaskReparenting of Activity1 is true.
First, start application1, load Activity1, and press the Home key to bring the task (assumed as task 1) to the background. Start application2. Activity2 is loaded by default.
What have we seen? Yes, it should have been Activity2, but we can see Activity1. In fact, Activity2 is also loaded, but Activity1 re-hosts, so we can see Activity1.
Case 2. If the intent of an Activity is loaded and the Flag is set to FLAG_ACTIVITY_NEW_TASK, it first checks whether a Task with the same taskAffinity exists. If yes, it directly hosts the Task, if the Task does not exist, recreate the Task.
Let's do a test.
First, we write an application, which has two activities (Activity1 and Activity2). AndroidManifest. xml is as follows:
<Application android: icon = "@ drawable/icon" android: label = "@ string/app_name">
<Activity android: name = ". Activity1"
Android: taskAffinity = "com. winuxxan. task"
Android: label = "@ string/app_name">
</Activity>
<Activity android: name = ". Activity2">
<Intent-filter>
<Action android: name = "android. intent. action. MAIN"/>
<Category android: name = "android. intent. category. LAUNCHER"/>
</Intent-filter>
</Activity>
</Application>
The Activity2 code is as follows:
Public class Activity2 extends Activity {
Private static final String TAG = "Activity2 ";
@ Override
Protected void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main2 );
}
@ Override
Public boolean onTouchEvent (MotionEvent event ){
Intent intent = new Intent (this, Activity1.class );
Intent. setFlags (Intent. FLAG_ACTIVITY_NEW_TASK );
StartActivity (intent );
Return super. onTouchEvent (event );
}
}
Then, let's write another application, MyActivity, which contains an Activity (MyActivity). AndroidManifest. xml is as follows:
<Application android: icon = "@ drawable/icon" android: label = "@ string/app_name">
<Activity android: name = ". MyActivity"
Android: taskAffinity = "com. winuxxan. task"
Android: label = "@ string/app_name">
<Intent-filter>
<Action android: name = "android. intent. action. MAIN"/>
<Category android: name = "android. intent. category. LAUNCHER"/>
</Intent-filter>
</Activity>
Start MyActivity, press the Home Key, return to the desktop, enable Activity2, and click Activity2 to go to Activity1. Then press the return key.
We found that the order for entering the Activity is Activity2-> Activity1, And the return order is Activity1-> MyActivity. This illustrates a problem,When Activity1 is started, it re-host to the Task where MyActivity is located.. (BecauseAndroid: taskAffinity = "com. winuxxan. task")
The preceding two examples demonstrate the use of TaskAffinity.
The following is a time to witness a miracle. Do not blink your eyes, comrades!
We will now combine the launchMode in the previous article with the taskAffinity mentioned in this article.
The first is the combination of singleTask loading mode and taskAffinity.
We still use the singleTask code of the article for a while, which is not listed here. Please read the previous article by yourself. The only difference is that we set MyActivity and Activity1 to the same taskAffinity and re-execute the test above.
We are surprised by the test results: the results of starting singleTask from the same application and starting different applications are completely different from those described above!
After thinking, we can combine execution from the same application and execution from different applications to get a conclusion:
When an application loads an Activity in singleTask mode, the Activity first checks whether a Task with the same taskAffinity exists.
1. If so, check whether the Activity is instantiated. If it has already been instantiated, destroy the Activity above the Activity and call onNewIntent. If it is not instantiated, the Activity is instantiated and merged into the stack.
2. If the Task does not exist, re-create the Task and merge it into the stack.
Use a process:
Then we will check the situation when the singleInstance mode is integrated into taskAffinity. We also use the singleInstance test example in this article, which is not listed here. Readers can refer to the previous article. The only difference is that we set MyActivity and Activity2 to the same taskAffinity.
We found that the test results also differ, that is, when the Activity is started from singleInstance, a Task is not re-created, instead, it enters the Task where the MyActivity with the same affinity is located.
Therefore, we can also draw the following conclusions:
1. When an application loads an Activity in singleInstance mode, if the Activity is not instantiated, re-create a Task and merge it into the stack. If the Activity has been instantiated, the onNewIntent of the Activity is called;
2. The Task where the Activity of singleInstance is located does not allow other activities. Any other Activity loaded from the Activity (assuming Activity2) will be put into other tasks, if a Task with the same affinity as Activity2 exists, Activity2 is created in the Task. If the Task does not exist, a new Task is generated and merged into the stack.