一、Activity四种启动模式

这4种启动模式都是通过在manifest中注册实现的。

<activity 
  android:name=".DemoActivity"
  android:launchMode="singleTask"/>

standard模式:所有activity都在同一个task栈中。每次启动activity,都会生成一个新的activity实例。
singleTop模式:所有activity都在同一个task栈中。启动activity时,如果该activity实例已经存在于栈顶,则复用该activity实例;否则,生成一个新的activity实例。
singleTask模式:所有activity都在同一个task栈中。启动activity时,如果该activity实例已经存在于栈中,则复用该activity实例,同时弹出该activity上面的所有实例;否则,生成一个新的activity实例。
singleInstance模式:会在一个新的task栈中启动该activity实例,且这个栈中有且只能有这一个activity实例。

二、Activity重要的启动标识

通过代码实现启动模式。

Intent intent = new Intent();
intent.setClass(context, DemoActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);

Intent.FLAG_ACTIVITY_NEW_TASK:在一个新的task栈中启动activity,但是并不是一定会在一个新的task栈中启动activity。如果系统为该activity找到一个极具亲和力(taskAffinity的值相等)的task栈,就不会在新的task栈中启动Activity。
Intent.FLAG_ACTIVITY_CLEAR_TOP:清空当前task栈中,该activity之上的所有activity实例,当前activity是否会重新onCreate,取决于是否与Intent.FLAG_ACTIVITY_SINGLE_TOP标记连用。
Intent.FLAG_ACTIVITY_SINGLE_TOP:只用Intent.FLAG_ACTIVITY_CLEAR_TOP当前Activity会重新onCreate,Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP组合使用,当前Activity不会重新onCreate。
Intent.FLAG_ACTIVITY_CLEAR_TASK:清空当前task栈中,所有activity实例。
Intent.FLAG_ACTIVITY_CLEAR_TASK+Intent.FLAG_ACTIVITY_NEW_TASK联合使用:清空当前task栈。然后在一个新的task栈中启动activity,但是并不是一定会在一个新的task栈中启动activity。如果系统为该activity找到一个极具亲和力(taskAffinity的值相等)的task栈,就不会在新的task栈中启动Activity。
Intent.FLAG_ACTIVITY_CLEAR_TOP+Intent.FLAG_ACTIVITY_NEW_TASK联合使用:清空当前task栈中,该activity之上的所有activity实例。然后在一个新的task栈中启动activity,但是并不是一定会在一个新的task栈中启动activity。如果系统为该activity找到一个极具亲和力(taskAffinity的值相等)的task栈,就不会在新的task栈中启动Activity。

三、task栈与task栈之间的关系

假如有3个task栈,task1中包含activity1,task2中包含activity2,task3中包含activity3和activity4,假如task1、task2、task3的位置关系是,task3位于顶部。
只有最上层task栈中的activity有启动别的activity的权限:上述例子中,activity3和activity4可以启动别的activity,activity1和activity2无法启动别的activity。
顶层activity所在栈一定位于顶部:上述例子中,假如activity3启动了activity1,那么task1将被提到顶部。activity1可以启动别的activity,activity2、activity3和activity4无法启动别的activity。

四、taskAffinity属性

<activity
  android:name=".DemoActivity"
  android:taskAffinity="123456"
  android:allowTaskReparenting="true"/>

taskAffinity用于标记当前activity应该属于哪个task栈:如果activity没有指定taskAffinity的值,那么就等于application的taskAffinity的值,如果application也没有指定,那么taskAffinity的值就等于包名。
默认情况下,Intent.FLAG_ACTIVITY_NEW_TASK不会在新的task栈中启动activity:因为能找到一个极具亲和力的task栈,默认情况下,activity的taskAffinity值都等于包名。
activity重新宿主:如果application1的activity1与application2的activity2的taskAffinity值相等,且application1的activity1的allowTaskReparenting设置为true。启动activity1后退到后台,再启动activity2时,activity1会重新宿主,也就是说会先看到activity1。

五、应用场景

LoginActivity->HomeActivity->ActivityA->ActivityB
假设从登陆页面(登录后页面finish),跳转到主页面,再跳转到ActivityA,再跳转到ActivityB。如果在ActivityB发现登陆过期,需要重新登录,并且登陆后需要重新进入主页面(相当于全部重新启动一遍)。
方案一:可以把HomeActivity设置为singleTask。
方案二:可以使用Intent.FLAG_ACTIVITY_CLEAR_TASK。
方案三:可以使用Intent.FLAG_ACTIVITY_CLEAR_TOP。


月笼冰泉
22 声望4 粉丝