深入Android系统【2】:launchMode (Instance)深入理解

前文Android Trick 4中已经对launchMode做了简介,近来使用中发现了一些理解不够的地方,特写出来和大家交流。

standard、singleTop、singleTask、singleInstance。


看SDK文档后,发现也不是很好理解上面几个的区别,尝试着综合各方面资料加上写程序实现来理解一下,整理出来。

分为两组去看比较好理解,第一组就是standard和singleTop,

standard:标准方式,启动一个Activity就创建一个实例。

在没有申明任何方式的情况下,这就是默认的Activity启动方式了。

singleTop:当Activity栈最顶层的A1启动另一个A1时,不会启动新实例。

这两个是人类最自然能够理解的东西了,如果某一个应用当中让你想到要用以上两个设置的话,多半是正确的;相反,如果一个应用中你想到的是用以下第二组中的两个设置的话,多半可能是用错的。这个要非常注意。

第二组就是singleTask和singleInstance,

singleTask:在Task范围内只产生一个实例。且这个实例启动完成后是在栈顶。

如果在一个apk应用里,singleTask的A启动了一个B,B中启动了A,这样的情况怎么办呢?如果A是在原Task中启动,系统会将B结束,然后保持原A在栈顶。

设置了"singleTask"启动模式的Activity的特点:

1. 设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的任务存在;如果存在这样的任务,它就会在这个任务中启动(此后在根据第2条检查),否则就会在新任务中启动。因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。

2. 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的Stack顶端中(官方文档说同时也在root of Stack,Stack底端,存疑1)。

singleInstance:launch一个singleInstance的Activity A会单独开一个Task 1,并且在此Task中仅有此Activity,也就是说在此Activity中再启动一个Activity B,这个B会在一个新的Task中开启。在B中launch一个A的话,Task 1就会到前面来,并且restart Activity A。由此可能,在全局范围内只有一个,即使在不同apk中调用(此处存疑2,有可能是不成立的)。它在Task中的上面下面都不会有其他Activity压着或被压着。


官方文档给的解释是这样的:

The default mode is "standard".

As shown in the table below, the modes fall into two main groups, with"standard" and "singleTop" activities on one side, and"singleTask" and "singleInstance" activities on the other.An activity with the "standard" or "singleTop" launch modecan be instantiated multiple times. The instances can belong to any taskand can be located anywhere in the activity stack. Typically, they'relaunched into the task that called startActivity()(unless the Intent object contains aFLAG_ACTIVITY_NEW_TASKinstruction, in which case a different task is chosen — see thetaskAffinity attribute).

In contrast, "singleTask" and "singleInstance" activitiescan only begin a task. They are always at the root of the activity stack.Moreover, the device can hold only one instance of the activity at a time— only one such task.

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 becreated to handle a new intent. However, if the target task already has anexisting instance of the activity at the top of its stack, that instancewill receive the new intent (in anonNewIntent() 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 ofthe 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.

The "singleTask" and "singleInstance" modes also differ fromeach other in only one respect: A "singleTask" activity allows other activities to be part of its task. It's always at the root of its task, but other activities (necessarily "standard" and "singleTop"activities) can be launched into that task. 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.

Use Cases Launch Mode Multiple Instances? Comments
Normal launches for most activities "standard" Yes Default. The system always creates a new instance of the activity in thetarget task and routes the intent to it.
"singleTop" Conditionally If an instance of the activity already exists at the top of the target task,the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating anew instance of the activity.
Specialized launches
(not recommended for general use)
"singleTask" No The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the systemroutes the intent to existing instance through a call to its onNewIntent() method, rather than creating anew one.
"singleInstance" No Same as "singleTask", except that the system doesn't launch anyother activities into the task holding the instance. The activity is always thesingle and only member of its task.

As shown in the table above, standard is the default mode and isappropriate for most types of activities. SingleTop is also acommon and useful launch mode for many types of activities. The other modes— singleTask and singleInstance — arenot appropriate for most applications,since they result in an interaction model that is likely to be unfamiliar tousers and is very different from most other applications.

Regardless of the launch mode that you choose, make sure to test the usabilityof the activity during launch and when navigating back to it fromother activities and tasks using the BACK key.

For more information on launch modes and their interaction with Intentflags, see the Tasks and Back Stackdocument.

"singleTask"
The system creates a new task and instantiates the activity at the root of the new task.However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time.

Note: Although the activity starts in a new task, theBACK key still returns the user to the previous activity.

"singleInstance".
Same as "singleTask", except that the system doesn't launch any other activities intothe task holding the instance. The activity is always the single and only member of its task;any activities started by this one open in a separate ta
android:taskAffinity
The task that the activity has an affinity for. Activities with the same affinity conceptually belong to the same task (to the same"application" from the user's perspective). The affinity of a task is determined by the affinity of its root activity.

The affinity determines two things — the task that the activity is re-parented to (see the allowTaskReparenting attribute) and the task that will house the activity when it is launched with the FLAG_ACTIVITY_NEW_TASK flag.

By default, all activities in an application have the same affinity. Youcan set this attribute to group them differently, and even placeactivities defined in different applications within the same task. To specify that the activity does not have an affinity for any task, setit to an empty string.

If this attribute is not set, the activity inherits the affinity set for the application (see the <application> element's taskAffinityattribute). The name of the default affinity for an application is the package name set by the <manifest> element.

所以,官方文档中可能没说清的疑点(产生矛盾了)有两个: (1) 相同taskAffinity属性值情况下,SingleTask Activity启动后并一定在root of the task stack,那就不符合always root of stack了,矛盾。  (2) 官方文档中明确说了SingleTask/Instance在Task范围内仅有一个,并暗示了全局范围内只有一个,即使在不同apk中调用。taskAffinity不同的情况下新开Task来承载Activity的话又怎么解释呢。既全局范围内存在多个SingeInstance的Activity的实例一定不会发生吗。只能说肯定的是同一taskAffinity值的SingleTask/Intance全局范围内仅存在一个。

这两个疑问暂时搁置,等之后我花点实际仔细研读相关framework代码后把它弄个明白吧。以后写一篇Back Stack\ Affinity\ App Model\ launchMode相结合理解的文章。

总体来说,从开发实践上来说,singleTop和standard比较好理解,行为比较符合一般逻辑。但牵涉到SingleTask/Instance的Activity,请实际测试验证之后来决定有无效果。


参考文档:

http://www.linuxidc.com/Linux/2011-08/41837p6.htm

http://developer.android.com/guide/topics/manifest/activity-element.html

http://groups.google.com/group/android-developers/browse_thread/thread/a24346d44a57fe5b?pli=1
发布了56 篇原创文章 · 获赞 6 · 访问量 51万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览