二:Activity的启动模式
我们知道,在默认情况下,当我们多次启动同一个Activity的时候,系统会创建多个实例并把他们一一放到任务栈中,当我们单击back键的时候,会发现这些Activity会一一回退。任务栈是一种:“后进先出”的栈结构每按一下back键就会有一个Activity出栈,知道栈空位置,当栈中无任何Activity的时候,系统就会回收这个任务栈。这里我们会发现一个问题:多次启动同一个Activity,系统会重复创建多个实例,这个是不是有点傻? 当然,Android肯定也考虑到了,所以也提供了启动模式来修改系统的默认行为。目前有四种启动模式:standard,singleTop,singleTask和singleInstance.
standard
标准模式,也是系统默认的模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。被创建的实例的生命周期符合典型情况下Activity的生命周期,即:它的onCreate,onStart,onResume都会被调用。这是一种典型的多实例实现,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的任务栈中。比如Activity A启动了Activity B(B是标准模式),那么B就会进入到A所在的栈中。
注意点: 当我们用ApplictionContext去启动standard模式的Activity的时候会报错,因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但是非Activity类型的Context并没有所谓的任务栈,所以就会出问题。解决方法是为待启动的Activity指定
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
标记位,这样启动就会为他创建一个新的任务栈,这个时候待启动的Activity实际上就是以singleTask模式启动的。
singleTop
栈顶复用模式。在这种模式下,如果新Activity已经位于任务栈的栈顶,那么就不会重新创建,同时他的onNewIntent方法会被回调,通过此方法的参数我们可以取出当前请求的信息。需要注意到是:onCreate,onStart,不会被系统调用。如果新的Activity的实例已经存在但不是位于栈顶,那么新Activity任然会被重新创建。
注意点:日常开发中的用到的点:
- 适合接收通知启动的内容显示页面。例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。从外界可能多次跳转到一个界面
- 还有比如打开一个页面,该页面上的按钮点击还会进入到该页面,这时候考虑用singleTop模式
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Common.Log('i', "onNewIntent");
setIntent(intent); //重新设置intent
}
singleTask
栈内复用模式。这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会调用onNewIntent方法。如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的 onNewIntent() )。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。