android之taskAffinity+allowTaskReparenting
taskAffinity:指定activity的宿主对象(task)。
可以指定activity自身所需要进入的task的实例对象,如果未指定,默认使用application中的taskAffinity(默认为包名),注意设置taskAffinity设置的String需要带前缀.,taskAffinity=".youname"。否则可能会报错INSTALL_PARSE_FAILED_MANIFEST_MALFORMED。
在这个文档里面其实讲了很多:http://developer.android.com/guide/topics/manifest/activity-element.html
这里给演示一些实例,以及解决一些疑问。
实验一:启动两个应用的launchmodetest1、launchmodetest2,launchmodetest1.MainActivity保留在默认task(launchmodetest1)中,launchmodetest2.MainActivity保留在默认task(launchmodetest2)中,而launchmodetest1.OtherActivity1+launchmodetest2.OtherActivity1保留在task(launchmodetest)中。
可以指定activity自身所需要进入的task的实例对象,如果未指定,默认包名。注意设置taskAffinity设置的String需要带前缀.,taskAffinity=".youname"。否则会报错INSTALL_PARSE_FAILED_MANIFEST_MALFORMED。
前期准备,打日志相关。
1 //<uses-permission android:name="android.permission.GET_TASKS"/> 2 private final String TAG = getClass().getName(); 3 @Override 4 protected void onResume() { 5 new Handler().postDelayed(new Runnable() { 6 @Override 7 public void run() { 8 ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 9 List<RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1); 10 if(null != runningTaskInfos){ 11 RunningTaskInfo info = runningTaskInfos.get(0); 12 Log.e(TAG, "task id:"+info.id+" base:"+info.baseActivity.toString()); 13 Log.e(TAG, "task id:"+info.id+" top:"+info.topActivity.toString()); 14 } 15 } 16 }, 500); 17 super.onResume(); 18 }
project:com.example.launchmodetest1/com.example.launchmodetest2。
activities:com.example.launchmodetest1.MainActivity/com.example.launchmodetest2.MainActivity
MainActivity:taskAffinity=".launchmodetest"。
project运行com.example.launchmodetest1,然后home:
01-08 22:26:43.915: E/com.example.launchmodetest1.MainActivity(27622): task id:302 base:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.MainActivity}
01-08 22:26:43.915: E/com.example.launchmodetest1.MainActivity(27622): task id:302 top:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.MainActivity}
project运行com.example.launchmodetest2:
01-08 22:27:11.695: E/com.example.launchmodetest2.MainActivity(27810): task id:302 base:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.MainActivity}
01-08 22:27:11.695: E/com.example.launchmodetest2.MainActivity(27810): task id:302 top:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
OK,launchmodetest2进入launchmodetest1栈中,但是关闭应用后重新再启动时,启动的都是launchmodetest1,结果和之前不一样。环境不是很纯粹,adb启动activity会带参数Intent.FLAG_ACTIVITY_NEW_TASK,导致结果有出入。
新增activities:com.example.launchmodetest1.OtherActivity1/com.example.launchmodetest2.OtherActivity1,MainActivity启动OtherActivity1,OtherActivity1:taskAffinity=".launchmodetest"。
使用startActivity(new Intent("com.example.launchmodetest1.OtherActivity1"),startActivity(new Intent("com.example.launchmodetest1.OtherActivity1"),测试不通过。
启动:startActivity(new Intent("com.example.launchmodetest1.OtherActivity1").setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)),startActivity(new Intent("com.example.launchmodetest1.OtherActivity1").setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))。
01-08 23:13:43.295: E/com.example.launchmodetest1.MainActivity(1495): task id:338 base:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.MainActivity}
01-08 23:13:43.295: E/com.example.launchmodetest1.MainActivity(1495): task id:338 top:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.MainActivity}
01-08 23:13:44.795: E/com.example.launchmodetest1.OtherActivity1(1495): task id:341 base:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.OtherActivity1}
01-08 23:13:44.795: E/com.example.launchmodetest1.OtherActivity1(1495): task id:341 top:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.OtherActivity1}
01-08 23:13:50.485: E/com.example.launchmodetest2.MainActivity(1328): task id:342 base:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
01-08 23:13:50.485: E/com.example.launchmodetest2.MainActivity(1328): task id:342 top:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
01-08 23:13:51.895: E/com.example.launchmodetest2.OtherActivity1(1328): task id:341 base:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.OtherActivity1}
01-08 23:13:51.895: E/com.example.launchmodetest2.OtherActivity1(1328): task id:341 top:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.OtherActivity1}
测试通过,launchmodetest1.MainActivity->launchmodetest1.OtherActivity1->home->launchmodetest2.MainActivity->launchmodetest2.OtherActivity1
连续返回:
01-08 23:14:42.405: E/com.example.launchmodetest1.OtherActivity1(1495): task id:341 base:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.OtherActivity1}
01-08 23:14:42.405: E/com.example.launchmodetest1.OtherActivity1(1495): task id:341 top:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.OtherActivity1}
01-08 23:14:44.015: E/com.example.launchmodetest2.MainActivity(1328): task id:342 base:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
01-08 23:14:44.015: E/com.example.launchmodetest2.MainActivity(1328): task id:342 top:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
结果:launchmodetest2.OtherActivity1->launchmodetest1.OtherActivity1->launchmodetest2.MainActivity,符合预期。
解释:launchmodetest1.MainActivity(task(launchmodetest1))->launchmodetest1.OtherActivity1(task(launchmodetest))->home((task(launcher)))->launchmodetest2.MainActivity((task(launchmodetest2)))->launchmodetest2.OtherActivity1((task(launchmodetest))),启动结束时,涉及4个task,task(launchmodetest1)在task(launcher)之下,task(launcher)之上有两个task,task(launchmodetest2)+task(launchmodetest),当前显示的是task(launchmodetest).aunchmodetest2.OtherActivity1,点击返回,回到task(launchmodetest).launchmodetest1.OtherActivity1,再返回,回到task(launchmodetest2),显示task(launchmodetest2).launchmodetest2.MainActivity,再返回,回到task(launcher)。
总结:taskAffinity+Intent.FLAG_ACTIVITY_NEW_TASK在第一次选择task时可以宿主到taskAffinity设置的task里。
allowTaskReparenting:允许activity的重新宿主对象(task)。
如果一个应用的activity1启动另一个应用的activity2(standard)且未使用Intent.FLAG_ACTIVITY_NEW_TASK,那么activity2有可能在该task里面完成自己的生命周期,回不到它原taskAffinity指定的task里面。
实验一:activity重新宿主
project:com.example.launchmodetest1/com.example.launchmodetest2。
activities:com.example.launchmodetest1.MainActivity、com.example.launchmodetest1.OtherActivity1/com.example.launchmodetest2.MainActivity
OtherActivity1:allowTaskReparenting="true"。
启动launchmodetest2.MainActivity->launchmodetest1.OtherActivity1
01-09 01:40:15.595: E/com.example.launchmodetest2.MainActivity(13210): task id:429 base:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
01-09 01:40:15.595: E/com.example.launchmodetest2.MainActivity(13210): task id:429 top:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
01-09 01:40:19.205: E/com.example.launchmodetest1.OtherActivity1(13080): task id:429 base:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
01-09 01:40:19.205: E/com.example.launchmodetest1.OtherActivity1(13080): task id:429 top:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.OtherActivity1}
home->launchmodetest2
01-09 01:42:15.055: E/com.example.launchmodetest2.MainActivity(13210): task id:429 base:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
01-09 01:42:15.055: E/com.example.launchmodetest2.MainActivity(13210): task id:429 top:ComponentInfo{com.example.launchmodetest2/com.example.launchmodetest2.MainActivity}
home->launchmodetest1
01-09 01:42:42.515: E/com.example.launchmodetest1.OtherActivity1(13080): task id:431 base:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.OtherActivity1}
01-09 01:42:42.515: E/com.example.launchmodetest1.OtherActivity1(13080): task id:431 top:ComponentInfo{com.example.launchmodetest1/com.example.launchmodetest1.OtherActivity1}
解释:launchmodetest2.MainActivity(task(launchmodetest2))->launchmodetest1.OtherActivity1(task(launchmodetest2))->launcher(task(launcher))->launchmodetest2(task(launchmodetest2))->launcher->launchmodetest1(task(launchmodetest1))此时launchmodetest1.OtherActivity1的task从(task(launchmodetest2))->(task(launchmodetest1))。