不管是网上的文章,还是官网的说明,想要理解并真正运用这些东西,都是比较吃力的,其实最好的做法就是写一个demo试验一下。
taskAffinity属性的用法,需配合flag的Intent.FLAG_ACTIVITY_NEW_TASK一起使用。
代码如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kv.app1">
<application android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<activity android:name=".App1Act1">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".App1Act2" android:taskAffinity="com.kv.app"/>
<activity android:name=".App1Act3"/>
<activity android:name=".App1Act4"/>
</application>
</manifest>
public class App1Act1 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act1);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(App1Act1.this, App1Act2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
public class App1Act2 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act2);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(App1Act2.this, App1Act3.class);
startActivity(intent);
}
});
}
}
用adb指令敲
adb shell dumpsys activity -p com.kv.app1
得到的结果如下:
Running activities (most recent first):
TaskRecord{265474e #13637 A=com.kv.app U=0 sz=3}
Run #5: ActivityRecord{1ba0a977 u0 com.kv.app1/.App1Act4 t13637}
Run #4: ActivityRecord{355957d5 u0 com.kv.app1/.App1Act3 t13637}
Run #3: ActivityRecord{35d8cacf u0 com.kv.app1/.App1Act2 t13637}
TaskRecord{152d506f #13636 A=com.kv.app1 U=0 sz=1}
Run #2: ActivityRecord{34633e3f u0 com.kv.app1/.App1Act1 t13636}
可以得出结论: App1Act2之后的activity, 被转到新的Task上面了,且新开了一个task。
taskAffinity属性的用法,也可以和singleTask一起使用。
代码如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kv.app1">
<application android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<activity android:name=".App1Act1">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".App1Act2" android:taskAffinity="com.kv.app" android:launchMode="singleTask"/>
<activity android:name=".App1Act3"/>
<activity android:name=".App1Act4"/>
</application>
</manifest>
public class App1Act1 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act1);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(App1Act1.this, App1Act2.class);
startActivity(intent);
}
});
}
}
敲adb指令
adb shell dumpsys activity -p com.kv.app1
结果如下
Running activities (most recent first):
TaskRecord{22e5352 #13639 A=com.kv.app U=0 sz=3}
Run #5: ActivityRecord{1e5166a1 u0 com.kv.app1/.App1Act4 t13639}
Run #4: ActivityRecord{314fb369 u0 com.kv.app1/.App1Act3 t13639}
Run #3: ActivityRecord{14093b54 u0 com.kv.app1/.App1Act2 t13639}
TaskRecord{39cf70e1 #13638 A=com.kv.app1 U=0 sz=1}
Run #2: ActivityRecord{4d3a2f9 u0 com.kv.app1/.App1Act1 t13638}
结论,与newtask一样,用singleTask也可单独新开一个task。
那如果只配了taskAffinity呢?
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kv.app1">
<application android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<activity android:name=".App1Act1">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".App1Act2" android:taskAffinity="com.kv.app"/>
<activity android:name=".App1Act3"/>
<activity android:name=".App1Act4"/>
</application>
</manifest>
public class App1Act1 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act1);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(App1Act1.this, App1Act2.class);
startActivity(intent);
}
});
}
}
结果如下
Running activities (most recent first):
TaskRecord{b44be7 #13640 A=com.kv.app1 U=0 sz=4}
Run #5: ActivityRecord{40b70fc u0 com.kv.app1/.App1Act4 t13640}
Run #4: ActivityRecord{222ccb93 u0 com.kv.app1/.App1Act3 t13640}
Run #3: ActivityRecord{15df41b u0 com.kv.app1/.App1Act2 t13640}
Run #2: ActivityRecord{de58251 u0 com.kv.app1/.App1Act1 t13640}
可以看出,单独配taskAffinity,不设置newTask或者singleTask,是不会新开一个任务的。
那么设置newTask和singleTask,不设置taskAffinity呢?
结果如下
Running activities (most recent first):
TaskRecord{39b500e4 #13641 A=com.kv.app1 U=0 sz=4}
Run #5: ActivityRecord{7eedc95 u0 com.kv.app1/.App1Act4 t13641}
Run #4: ActivityRecord{29de1620 u0 com.kv.app1/.App1Act3 t13641}
Run #3: ActivityRecord{3da07ab u0 com.kv.app1/.App1Act2 t13641}
Run #2: ActivityRecord{16a7e488 u0 com.kv.app1/.App1Act1 t13641}
可以看出,也不会新开一个任务。
通过上面的实验,可以加深对概念的理解
1.taskAffinity表示当前activity具有亲和力的一个任务,大致可以这样理解,这个 taskAffinity表示一个任务,这个任务就是当前activity所在的任务。
2.在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务。
一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity。
3.这个属性决定两件事:当activity被re-parent时,它可以被re-paren哪个任务中;当activity以FLAG_ACTIVITY_NEW_TASK标志启动时,它会被启动到哪个任务中。(这个比较 难以理解,请结合<activity>中的属性allowTaskReparenting和Intent中的标志 FLAG_ACTIVITY_NEW_TASK加以理解)
4.默认情况下,一个应用中的所有activity具有相同的taskAffinity,即应用程序的包名。我们可以通过设置不同的taskAffinity属性给应用中的activity分组,也可以把不同的 应用中的activity的taskAffinity设置成相同的值。
5. 为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task。
通俗点说,taskAffinity要结合newTask和singleTask一起使用。