1.叨叨
上篇说了几种常见的应用,但总感觉不太舒服,这篇将通过 A,B,C,D 四个界面解析;
2.了解 LaunchMode
在 AndroidManifest.xml
中配置 activity
的时候的一个属性,比如:
<activity
android:name=".OnePageActivity"
// i'm here
android:launchMode="standard"
android:taskAffinity="cn.labelnet.task" />
比如:
如图所示: 一共四个值
- singleTask
- singleInstance
- singleTop
- standard
这四个值只用在 activity 启动的时候才能起作用
其中
- singleTop 和 standard 可以被实例化多次,实例可以属于多个 task , 可以处于任何 back stack
- singleTask 和 singleInstance 不可以被实例化多次,常用语一个 task 堆栈,处于 back stack 开始部分
2.1 singleTop
当进入A页面的时候系统会自动 在 Task
堆栈中检测当前栈顶元素是否是我们需要访问的A页面的Activity
,如果栈顶元素是我们的A页面,那么将重用A页面, 同时回调 onNewIntent()
函数
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
比如 :
堆栈页面顺序为 A,B,C,D 在 D页面中跳转 D页面, 会重用D实例,顺序还为 A,B,C,D
2.2 standard
普通堆栈模式,默认模式,可以不写;
当前堆栈顺序为 A,B,C , 在C中进入D页面,则顺序为 A,B,C,D
2.3 SingleTask
此模式,不会重建新的实例,如果访问这个实例,会将这个实例上面的堆栈清除掉;
当前堆栈顺序为 A,B,C,D , A页面被修饰为SingleTask, 在D中进入B页面 ,则当前堆栈信息为 A,B
2.4 SingleInstance
此模式,将会重建新的堆栈信息,并脱离当前 task 堆栈
当前堆栈顺序为 A,B,C , 在C页面进入被修饰的D页面时,当前的堆栈信息为两个:
Task : A,B,C 和 Task : D
3.Intent Flag 跳转说明
- setFlag() 设置新的 flag
- addFlag() 在当前的 flag 上添加其它 flag
3.1 FLAG_ACTIVITY_NEW_TASK
默认类型,重新创建实例;
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
当前的堆栈顺序为 A,B , 如果在B上进入C , 那么当前顺序为 A,B,C
如果配合 android:taskAffinity
使用,会创建新的实例在新的堆栈中;
<activity
android:name=".C"
android:taskAffinity="cn.labelnt.task"
/>
当前堆栈顺序为 A,B , 如果在B上进入C ,则当前的堆栈顺序为 Task 1 : A,B 和 Task 2 : C
3.2 FLAG_ACTIVITY_SINGLE_TOP
这种模式和 Launch Mode
的 single top
设置是一样的
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
堆栈页面顺序为 A,B,C,D 在 D页面中跳转 D页面, 会重用D实例,顺序还为 A,B,C,D
3.3 FLAG_ACTIVITY_CLEAR_TOP
这种模式和 LaunchMode
的 single task
设置是一样的;
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
当前堆栈顺序为 A,B,C,D , A页面被修饰为SingleTask, 在D中进入B页面 ,则当前堆栈信息为 A,B
合并使用
如果在返回 B 页面,不想 B 页面重新创建,需要设置 Single Top :
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
会重新回调 B 页面的 onNewIntent() 方法;
3.4 FLAG_ACTIVITY_NO_HISTORY
当前进入的页面不会加入堆栈中,而在其上面启动的会加入到栈中
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
当前堆栈顺序为 A,B , 如果C页面被修饰,在B页面启动C页面,那么当前的堆栈顺序还为 A ,B
如果在C上打开D页面,D页面未被修饰,那么当前的堆栈顺序为 A,B,D
3.5 FLAG_ACTIVITY_BROUGHT_TO_FRONT
这个模式和standard 模式一样,普通堆栈
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
startActivity(intent);
}
当前堆栈顺序为 A,B,C , 在C中进入D页面,则顺序为 A,B,C,D
3.6 FLAG_ACTIVITY_REORDER_TO_FRONT
可以改变堆栈顺序,如果当前堆栈中存在,会取到 top 上,执行 restart() - onstart() - onResume()
并执行回调 onNewIntent() 方法;
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
当前堆栈顺序为 A,B,C,D , 如果在 D 中启动 B , 那么堆栈顺序变为 A,C,D,B