Android LauncherModel 启动模式
在各种论坛上,存在着各种关于LauncherModel启动模式的分析,但是大都写得似是而非,只是简单阐明了四种模式的概念性的解读,并没有深入解析Activity栈的情况,这边文章我将从Activity栈的情况去进行解析.
- Launcher
首先,我们先看起来Launcher对于四种模式的影响,我们知道点击HOME键之后我们都会回到Launcher界面,要打开应用我们是从Launcher中点击应用图标打开的,所以我们先关注一下在Launcher中应用的点击情况:
boolean startActivitySafely(View v, Intent intent, Object tag) {
boolean success = false;
try {
success = startActivity(v, intent, tag);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
}
return success;
}
而这个intent:
intent.setFlag(Intent.FLAG_ACTIVITY_NEW_TASK);
也就是说,从桌面启动的activity都赋予了Intent.FLAG_ACTIVITY_NEW_TASK属性.
这个属性的意义在于如果从ActivityA启动ActivityB, 如A和B处于同一个应用,那么他们将处于同一个Activity栈中(栈1:A->B),但是如果不处于同一个应用,那么将新建一个Activity栈,并将B放入其中(栈1:A 栈2:B).
先会查找是否存在和被启动的Activity具有相同的亲和性的任务栈),如果有,刚直接把这个栈整体移动到前台,并保持栈中的状态不变,即栈中的activity顺序不变,如果没有,则新建一个栈来存放被启动的activity
别急,这里是为了更加详细的分析各种点击的栈的情况,所以介绍了Launcher的点击下,以免引起混淆
standard
第一种模式,即标准模式,他在于每次启动activity都会创建一个activity实例,并且加入栈中.
若有应用A中的Activity A,他的LauncherModel为standard,我们从Launcher中启动应用,并且再从A中启动A(前面我们已经介绍了在Launcher中启动应用,它的默认Flag都为NEW_TASK),那么此时的栈的情况为:
栈1:LauncherActivity
栈2:ActivityA1 ActivityA2singleTop
这种它的关注点在于Activity的栈顶,如果当前Activity实例是打算新建的Activity的实例,则调用onResume,如果不是则新建一个调用onCreate,我们来关注一下栈的情况
a.从Activity A打开Activity A,在打开Activity A
栈:ActivityA1
此时栈中一直只有一个ActivityA实例,而且还是同一个,因为调用的只是onResume而已
b.从A->B->A
栈:A1->B1->A2
因为从B再次打开A时,因为此时的栈顶Activity是B,则会新建一个A的实例singleTask
首先会遍历Activity栈,如果栈中不存在欲创建的Activity实例,则创建该Activity实例并且放在栈顶,但是如果在遍历的过程中存在该Activity实例,则pop掉该Activity实例上面的所有其他Activity实例(这是栈的特性,如果要获取到栈中间的某个数据,则需要pop掉这个数据之上的所有数据)
a.A->A->A
栈:A1
栈中一直存在一个不变的Activity A1的实例,每次调用onResume
b.C->A->B->B->B->A
栈:C1->A1
在第二次要创建ActivityA的实例时,会遍历Activity栈,检索到存在Activity实例,则POP掉了其中的三个B