Android开发笔记(十六)——Activity的4种启动模式
AndroidManifest
中比较重要的一个属性是 launchMode
启动模式:
Acyivity的 android:launchMode
四个属性:
- standard:标准模式,默认
- singleTop:Task栈顶复用模式(栈是先进后出,当我们启动一个Activity,如果这个目标Activity位于栈顶,不会创建一个新的实例,而是会直接复用这个栈顶的Activity)
- singleTask:Task栈内复用模式(不一定要在栈顶,只要栈内有就可以直接复用,不管位置)
- singleInstance:全局单例模式(前两个必须是在同一个栈内,这个是只要在存取的所有栈里面只要有的就可以复用)
测试准备:
继续使用上次创建的AActivity和BActivity。
在AActivity中的onCreate函数中添加:
Log.d("AActivity","-----onCreate-----");
Log.d("AActivity","---taskid:"+getTaskId()+"--- ---hash:"+hashCode()+"---");
logtaskName(); //打印任务栈的名称
onNewIntent
和 logtaskName
函数写在onCreate函数后面:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d("AActivity","-----onNewIntent-----");
Log.d("AActivity","---taskid:"+getTaskId()+"--- ---hash:"+hashCode()+"---");
logtaskName(); //打印任务栈的名称
}
private void logtaskName(){
try {
ActivityInfo info = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
Log.d("AActinity",info.taskAffinity); //info.taskAffinity可以理解为当前Activity所在任务栈的名称
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
在BActivity中同样操作,在A添加一个Button使其在A页面跳转到A页面,在B添加一个Button使其在B页面跳转到A页面。
standard
- Activity是由任务栈管理的,每启动一个Activity,就会被放入栈中,按返回键,就会从栈顶移除一个Activity。
- standard是默认的启动模式,即标准模式。每启动一个Activity,都会创建一个新的实例。
演示:
- 从主页面MainActivity跳转到AActivity中时,MainActivity的任务栈为包名,后面所有的Activity都隶属于这个栈
- 当没有设置任务栈的名称时候,默认为应用的包名
- 当点击Button从A页面跳转到A页面时,这里taskid是一样的,也就是这两个Activity处在同一个任务栈当中,但是他们的哈希码是不一样的,表示这两个Activity不是同一个实例,说明从A页面跳转到A页面时又创建了一个新的实例。(因为是标准启动,每启动一个Activity,都会创建一个新的实例)
- 当点击Jump从A页面跳转到B页面时:可以看到任务栈还是相同的,但是哈希码不同,因为BActivity本身不存在于任务栈当中,是一个新的实例
singleTop
- 当要启动的目标Activity已经位于栈顶时,不会创建新的实例,会复用栈顶的Activity,并且其
onNewIntent()
方法会被调用; - 如果目标Activity不在栈顶(在栈里但不在顶部;或者根本不在栈内),则和standard一样创建新的实例。
演示:
- 从主页面MainActivity跳转到AActivity中时,调用onCreate方法
- 从AActivity再次跳转到AActivity中时(此时目标Activity是AActivity,目标Activity在栈顶中),这时打印出来的哈希码和之前一直,也就是说此时复用了栈顶的Activity,并且其onNewIntent()方法被调用
- 从AActivity跳转到BActivity中时(此时目标Activity是BActivity,目标Bctivity不在栈中),此时哈希码发生了变化,说明创建了新的实例。
- 从BActivity再次跳转到AActivity中时(此时目标Activity是AActivity,目标Activity在栈中但是不在栈顶中),此时哈希码发生了变化,说明创建了新的实例。
singleTask
- 在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Activity,并调用其
onNewIntent()
方法,并且该Activity上面的Activity会被清除(出栈); - 如果栈中没哟,则创建新的实例。
当没有设置任务栈的名称时候,默认为应用的包名,如果自己有设置任务栈名称(在 AndroidManifast
中对应的activity设置属性 android:taskAffinity
),那就不属于默认包名的任务栈了。当从这个Activity开始启其他Activity时候,都会被加入这个新设置的栈中。
singleInstance
- 全局复用,不管哪个Task栈,只要存在目标Activity就复用;
- 每个Activity占有一个新的Task栈。
通常使用standard和singleTop、singleTask,singleInstance用的比较少。