Activity 四种启动模式分析
android的一个伟大的设计就是Activity,activity的设计是google工程耗费很大的精力和时间才搞出来的,activityde的生命周期管理,启动模式这些功能都是他的精髓和精华。在项目中我使用最多的还是Activity,对于如何更好的使用Activity的启动模式对于我们在项目的开发中是很重要的。熟练使用LauncherMode的这几种模式,能够提高项目的稳定性,同时还能优化用户体验。activity的启动模式有四种,分别是Standard,SingleTop,SingleTask,SingleInstance 这四种。下面我们通过实例来分析。
官方的文档:官网LauncherMode
1.Standard方式
官网上面说这个是默认的一种启动方式,这种启动方式只要只要startActivity()就会重新生成一个Activity的实例,不管在启动的Task中是不有这个activity的实例,都会重新创建一个新的实例。简单的例子,A--->B---->C--->A。在这样的一个执行过程中,创建了二个A对象,因为Activity的对象是存放在一个Task的栈里面的,由于栈的进出是“先进后出”的。所以当我们关闭页面的时候也是先,关闭A的第二个对象,然后是C对象,接着是B,最后才是A的第一个对象。这种方式是用的比较多,看下面的demo,首页--->启动A--->启动B--->启动A,这几个页面的启动方式都是Standard的
方式来启动的,看输出的log信息如下图
结论:采用默认的方式启动Activity的话,每次启动一个就会创建一个新的对象。不管你要启动的Activity是在Task的栈顶还是栈底。
2.SingleTop方式
官方文档有这么一段话,The "standard
" and "singleTop
" modes differ from each other in just one respect: Every time there's a new intent for a "standard
" activity, a new instance of the class is created to respond to that intent. Each instance handles a single intent. Similarly, a new instance of a "singleTop
" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an onNewIntent()
call); a new instance is not created. In other circumstances — for example, if an existing instance of the "singleTop
" activity is in the target task, but not at the top of the stack, or if it's at the top of a stack, but not in the target task — a new instance would be created and pushed on the stack.
这段介绍大概的意思是说singleTop的使用也是很多的,和standard只有一一个方面的不一样,就是当SingleTop的Activity在当前的栈的顶部已经创建了实例的话,他就不会再去新建一个实例,会执行这个方法onNetIntent();而不会再执行onCreate()方法。类似于这种启动方式,首页-----A -----B-----B;这种情况的第二个B不会再执行onCreate(),不会再创建新的实例在当前的栈顶,而是使用原来栈顶的实例。但是当执行这种(首页----A------B-----A)这种方式的话,就和standard这种方式是一样的。下面我们在AndroidManifests.xml中将B和A都设置成SinglTop的启动方式来看看上面二种情况的执行日志;
采用A----B----B 输出日志
通过日志,我们看到因为B已经在这个栈中有对象且在当前栈的栈顶,并且B的启动方式为singletop,这样当再启动一个B的页面时,系统不会再新建B的对象,而是执行在栈顶的B的对象的onNetIntent()方法。
采用A----B----A这种方式的log如下:
通过日志我们看出,将A 和B的页面都设置为SingleTop的模式的时候,在当前的栈中已经存在A的对象,但是由于不在当前的任务栈的栈顶,所有他还是会从新创建任务一个新的A的对象。这种方式就和"standard"的启动方式是一样的了。设置启动下一个页面的启动方式也可以采用通过Intent.setFlags( FLAG_ACTIVITY_CLEAR_TOP
)来做;
这种模式比较适合哪种类似于自定义相册选取照片的功能。还有一种就是页面跳转如果点击太快,也不会创建二个重复的对象。
3.SingleTask模式
这种启动模式用的相对来说比较少,SingleTask 和前面介绍的二种都是不一样的,这种模式的使用是要分特定场合的。
3.1 同一应用程序中
在同一个Task中,启动SingleTask的Activity的时候如果这个栈中没有这该对象的话会创建一个,但是如果已经存在的话就会直接调用它的onNewIntent()方法,不会再创建新的实例,不管这个实例是不是在这个Task的栈顶,例如首页----A----B-----C-----A这样的一个流程其实执行还是首页-----A----B----C----前面A(实例)onNetIntent();看实例日志;
SingleTask方式启动的Activity如果是当回退的时候会关闭掉他上面的全部页面,他上层的task会全部执行finish()方法。比如说首页-----A(SingleTask)-----B-----C;当A页面关闭的时候回一并关闭B和C,这样在Task中只有首页的实例。接着上面的流程,我们在A页面按下返回键。输入的日志如下:
通过上面二个实例的运行结果我们得知:采用SingleTask启动的Activity在同一个应用只有一个实例,不管这实例是不是在Task的栈顶,只要再次启动它的话都不会再重新创建新的实例会执行onNetInent()方法,在SingleTask实例中执行返回操作的话,在当前的Task中将该实例上层的Activity从这个Task移除掉。
3.2 跨应用之间
应用程序间启动SingleTask Activity的实例,如果没有该实例的话就创建该实例,然后将其存放在一个新建的task中,比如调取系统相册,还有拨打电话这些都是跨应用程序之间来启动一个新的SingleTask Activity,同时将这个实例存放在一个新的Task中。
这种场景常见的就是通过一个广播来启动一个通知页面的时候就必须采用这种方式来启动,启动的那个页面的启动方式就是SingleTask,他会存放在一个新建的Task中。当在新建的task中你可以执行一些列操作,当按返回的时候回将这个task中的所有Activity都移除同时将这个task置于后台。常见的调用打电话,调用发短信等等都是这种方式。
但是在项目使用这种方式 要注意,因为当关闭采用SingleTask启动的Activity的时候,会一并关闭他所在的task的上层的所有的Activity。所以在使用要中特别注意。我们使用这个有二种方式,一种直接在AndroidManifests.xml中配置,另外一种是通过Intent设置setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
);来实现。
4 SingleInstance方式
官网上面说这种模式和上面SingleTask很相似,但是唯一不同的是singleTask启动的Activity可以和其他的方式启动的(standard和SingleTop)Activity在用一个Task中,而采用SingleInstance的Activity有自己独特的地方,看官网 A "singleInstance
" activity, on the other hand, permits no other activities to be part of its task. It's the only activity in the task. If it starts another activity, that activity is assigned to a different task — as if FLAG_ACTIVITY_NEW_TASK
was in the intent.
这个意识是指采用SingelInstence的activity所在的task不会有其他的Activity存在,意思就是通过其他singleInstance的Acitivyt来启动一个新的Activity的话,会新建一个Task来保存这个新建的activity,同样的如果其他的Activity来启动一个SingleInstance的Activity的话会,也会重新生成一个新的Task,并且这个activity是在task的顶部。
5 总结
通过上面的实例和官网上面的分析得知,LauncherMode 分为两组:第一组standard和SingleTop是一组用的比较多,他们二个唯一的区别就是SingleTop如果在当前Task的顶部,同时在startActivity()这个Activity的时候就不会再 创建新的实例,而是之心该实例的onNewIntent()方法,其他情况下的用法是一样的;第二组SingleTask和SingleIntance这一组用的比较少,要结合特定情况来使用,这一组的使用区别是比较大的,看上面的文章,详细的讲解,在我们开发APP的过程中要合理的使用Activity的启动模式来使我们的APP更加的快捷,流畅,提高用户体验。如果有写的不好的还忘指点。