一、四种启动模式详细介绍
以下内容完全摘抄自小路飞_掘金
介绍 Android 启动模式之前,先介绍两个概念task和taskAffinity
- task:翻译过来就是“任务”,是一组相互有关联的 activity 集合,可以理解为 Activity 是在 task 里面活动的。 task 存在于一个称为 back stack 的数据结构中,也就是说, task 是以栈的形式去管理 activity 的,所以也叫可以称为“任务栈”。
- taskAffinity:官方文档解释是:"The task that the activity has an affinity for.",可以翻译为 activity 相关或者亲和的任务,这个参数标识了一个 Activity 所需要的任务栈的名字。默认情况下,所有Activity所需的任务栈的名字为应用的包名。 taskAffinity 属性主要和 singleTask 启动模式或者 allowTaskReparenting 属性配对使用。
4种启动模式
- standard:标准模式,也是系统默认的启动模式。假如 activity A 启动了 activity B , activity B 则会运行在 activity A 所在的任务栈中。而且每次启动一个 Activity ,都会重新创建新的实例,不管这个实例在任务中是否已经存在。非 Activity 类型的 context (如 ApplicationContext )启动 standard 模式的 Activity 时会报错。非 Activity 类型的 context 并没有所谓的任务栈,由于上面第 1 点的原因所以系统会报错。此解决办法就是为待启动 Activity 指定 FLAG_ACTIVITY_NEW_TASK 标记位,这样启动的时候系统就会为它创建一个新的任务栈。这个时候待启动 Activity 其实是以 singleTask 模式启动的。
- singleTop:栈顶复用模式。假如 activity A 启动了 activity B ,就会判断 A 所在的任务栈栈顶是否是 B 的实例。如果是,则不创建新的 activity B 实例而是直接引用这个栈顶实例,同时 onNewIntent 方法会被回调,通过该方法的参数可以取得当前请求的信息;如果不是,则创建新的 activity B 实例。
- singleTask:栈内复用模式。在第一次启动这个 Activity 时,系统便会创建一个新的任务,并且初始化 Activity 的实例,放在新任务的底部。不过需要满足一定条件的。那就是需要设置 taskAffinity 属性。前面也说过了, taskAffinity 属性是和 singleTask 模式搭配使用的。
- singleInstance:单实例模式。这个是 singleTask 模式的加强版,它除了具有 singleTask 模式的所有特性外,它还有一点独特的特性,那就是此模式的 Activity 只能单独地位于一个任务栈,不与其他 Activity 共存于同一个任务栈。
二、重点说明
1. android:taskAffinity属性
singleTask一般和taskAffinity属性搭配使用
每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的属性就等于Application指明的taskAffinity。如果Application也没有指明,那么该taskAffinity的值就等于包名
只要知道这个Activity是以哪种启动模式启动的(可能在AndroidManifest中指定,也可能在代码中指定),再根据上述规则,就能指定它要进入的是哪个任务栈
举例说明:FirstActivity.class中点击按钮启动SecondActivity.class
/**
* <pre>
* author : 杨丽金
* time : 2018/04/23
* desc :
* </pre>
*/
public class FirstActivity extends BaseActivity {
@BindView(R.id.btn_jump)
Button btn_jump;
@Override
public int getLayoutId() {
return R.layout.activity_first;
}
@Override
public void initData(Bundle savedInstanceState) {
}
@Override
public void setListener() {
btn_jump.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// 启动SecondActivity,以singleTask模式启动,该模式和taskAffinity属性搭配使用
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
-
当SecondActivity在清单文件中的配置如下时:
以SingleTask模式启动的SecondActivity,和FirstActivity在不同任务栈中
<activity android:name=".module.startmode.FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!--该配置表示:1,通过正常方式启动该Activity,该Activity就会在原有任务栈中启动(启动该Activity的任务栈)
2,若想要taskAffinity属性生效,需要在启动Activity时设置Flag为FLAG_ACTIVITY_NEW_TASK-->
<activity android:name=".module.startmode.SecondActivity"
android:taskAffinity="com.whut.ylj"/>
-
当SecondActivity在清单文件中的配置如下时:
以SingleTask模式启动的SecondActivity,和FirstActivity在同一任务栈中
<activity android:name=".module.startmode.FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".module.startmode.SecondActivity"/>
2.onNewIntent()
当Activity的启动模式设置为sinleTop、singleTask时,如果Activity栈中有该Activity,想要再次打开Activity时,Activity不会重新创建,只会回调该方法。
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
网友评论