有多个activity singletaskk 的activitty 的任务栈

四种启动模式介绍--SingleTask理解_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
四种启动模式介绍--SingleTask理解
上传于|0|0|暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢1427人阅读
Android开发(11)
&span style=&font-family: Arial, Helvetica, sans- background-color: rgb(255, 255, 255);&&原文地址:&/span&&a target=_blank href=&/blog/understand-android-activity-launchmode/en& target=&_blank& style=&font-family: Arial, Helvetica, sans- background-color: rgb(255, 255, 255);&&/blog/understand-android-activity-launchmode/en&/a&
& & & &Activity是Android在内存管理的优秀架构中最好的概念之一,它使得多任务能够在Android这个著名的移动操作系统完美地运行。
& & & &不管怎样,Activity不仅仅是被加载到屏幕上的(这句翻译怪怪的!),它的加载方式也需要我们关注。关于Activity加载这个话题,有着很多的细节。这些细节中真正重要的一个就是launchMode,而它也是我们将要在本文中讨论的。
& & & & & & 因为每个Activity都有着不同的使用目的。有的Activity是设计用来独立处理每个一个发送来的Intent,例如在email客户端中撰写邮件的Activity,而有的则是以“单例”的模式工作,例如一个email的收件箱Activity。
& & & &这就是为什么在指定一个Activity时,到底是需要创建一个新的还是使用已有的这个问题是比较重要的了,这个问题会也许导致不好的用户体验。感谢Android的核心工程师,他们针对这个问题特别提供了一个launchMode属性来容易地解决。
指定launchMode
& & & & & 最基本的,我们可以直接在AndroidManifest.xml中的&activity&标签中作为一个属性来指定launchMode:
android:name=&.SingleTaskActivity&
android:label=&SingleTask launchMode&
android:launchMode=&singleTask&/&一共有4种可以用的launchMode,我们将一个接一个的研究。
& & & 这是一个默认模式。
& & & 设定为这个模式的Activity在收到Intent时总是创建一个新的Activity。想象一下,如果有10个Intent要撰写email,那么就会有10个Activity加载出来响应每一个Intent。这样就会导致在一个设备上加载的这种Activity的数量不会有限制。
& & & Lollipop(Android 5.0)之前的Android版本表现形式
& & & 这种Activity将会被创建并放在发送Intent的Activity所在任务栈的顶端(如下图所示)。
& & & &下面的图片展示了但我们向一个standard模式的Activity分享图片时会发生什么。跟之前描述的一样,这个Activity将会被放在相同任务栈中,尽管这两个Activity来自不同的应用。
& & & &在任务管理器中,你将会看到如下界面。
& & & 如果我们从该应用切换到另一个,然后再切回Gallery,我们将会看到standard加载模式的Activity是放在Gallery的任务栈顶端的。这导致了如果我们想在Gallery中做些什么就必须先结束这个新增Activity中的工作。
Android Lollipop(Android 5.0)中的表现形式:
& & & 如果这些Activity是在同一个应用中的,那么它的加载方式跟Lollipop之前版本中形式一样,会把新的Activity放在发送Intent的Activity所在任务栈的顶端。
& & & 但是当Intent是来自另一个不同的应用时,就会创建一个新的任务,然后这个新建的Activity会以一个根Activity的形式放在新建的任务中。
& & & 在你的任务管理器中你将会看到如下的界面:
& & & 这种改变发生的原因是Lollipop中的任务管理器系统进行了修改,使得表现地更好、更有道理。在Lollipop中,你可以仅仅切换回Gallery,因为它们在不同的任务栈中。你可以启动另一个Intent,然后就像之前那样,一个新的任务将会被创建来响应该Intent。
& & & 这种类型Activity的的一个例子就是撰写email的Activity或者一个社交网络应用中发帖的Activity。如果你想让Activity独立的响应不同的intent,那就考虑使用standard launchMode。
& & & singleTop模式跟standard模式很像,因为singleTop模式的Activity实例也可以创建很多。唯一不同的就是如果已经存在一个相同类型的Activity实例在Intent发送者所在任务栈的顶端,就不会再创建新的Activity,相反,这个Intent将会通过onNewIntent()方法发送给已经存在的Activity。
& & & 在singleTop模式中,你必须在onCreate()和onNewIntent()方法中处理一个进来的Intent,以确保在任何情况下都可以有效工作。
& & & 一个使用这种加载模式的例子就是“查找功能”。考虑一下创建一个将使你进入SearchActivity查看搜索结果的搜索框,为了更好的用户体验,一般我们总是将搜索框放在搜索结果页面中以便用户不需要按返回键就可以直接搜索。
& & & 现在想象一下,如果我们总是加载一个新的SearchActivity来响应新的搜索结果,如果搜索10次将会有10个SearchActivity。当你按返回键返回时,你必须按10次才可以穿过这些搜索结果Activity,然后返回到你的根Activity。
& & & 如果有一个SearchActivity在任务栈的顶端,我们最好是向存在的Activity实例发送Intent,然后让它更新搜索结果。现在就只有一个SearchActivity在任务栈的顶端,你可以简单按一次返回键就可以返回到以前的Activity。
& & & 不管怎样,singleTop会和调用者工作在相同的任务栈中。如果你希望发送一个Intent到放在另一栈顶端已经存在的Activity,我不得不遗憾的告诉你这是不行的。如果Intent是从另一个应用发送到singleTop Activity的,一个新的Activity会以standard加载模式加载出来(Lollipop之前版本:新Activity放在调用者栈顶端,Lollipop:创建一个新的任务栈)。
singleTask
& & & 这个模式与standard和singleTop有着很大不同。singleTask加载模式的Activity在系统中只允许有一个实例(也叫单例)。如果系统中已经存在一个Activity实例,持有实例的任务将会被移动到顶端,同时Intent将通过onNewIntent()方法传递。否则,将会创建一个新的Activity然后放在合适的任务栈中。
& & & 在相同的应用中
& & & 如果系统中不存在一个singleTask的Activity,系统会创建一个新的Activity然后让在相同任务栈顶端(如下图所示)。
& & & 但是如果系统中已经存在,任务栈中所有放在singleTask Activity上面的Activity将会被自动并且残酷的以正常方式销毁掉(触发生命周期),从而使得我们想要的Activity出现在栈的顶端。同时,Intent将通过可爱的onNewIntent()方法发送到singleTask Activity。
& & & 从用户体验角度来讲,这是不好的,但是它就是这样设计的。。。
& & & 你需要注意文档中提到的一件事:
The system creates a new task and instantiates the activity at the root of the new task.& & & 但是从实验老看,它好像不是像文档中描述那样工作的。singleTask Activity仍然会堆积在任务栈顶端,正如我们从dumpsys activity命令显示中看到的那样:
Task id #239
TaskRecord{428efe30 #239 A=com.thecheesefactory.lab.launchmode U=0 sz=2}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x cmp=com.thecheesefactory.lab.launchmode/.StandardActivity }
Hist #1: ActivityRecord{429a88d0 u0 com.thecheesefactory.lab.launchmode/.SingleTaskActivity t239}
Intent { cmp=com.thecheesefactory.lab.launchmode/.SingleTaskActivity }
ProcessRecord{65:com.thecheesefactory.lab.launchmode/u0a123}
Hist #0: ActivityRecord{425fec98 u0 com.thecheesefactory.lab.launchmode/.StandardActivity t239}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x cmp=com.thecheesefactory.lab.launchmode/.StandardActivity }
ProcessRecord{65:com.thecheesefactory.lab.launchmode/u0a123}
& & & 如果你想让singleTask Activity像文档中描述那样工作:创建一个新的任务并将Activity作为任务的根Activity。你需要指定taskAffinity属性:
android:name=&.SingleTaskActivity&
android:label=&singleTask launchMode&
android:launchMode=&singleTask&
android:taskAffinity=&&&
& & & 下面是我们尝试加载singleTaskActivity的结果:
& & & 你需要根据Activity的表现来决定是否要指定taskAffinity属性。
& & & 和另一个应用协作
& & & 一旦Intent是来自另一个应用,并且系统中不存在一个响应Intent的Activity实例,系统会创建一个新的Task并将新建的Activity以根Activity的形式放在新建的Task中。
& & & 除非存在一个这个应用的任务,并且这个任务是要调用的singleTask Activity的拥有者,这样的话新建的Activity将会被放在该任务的顶端。
& & & 如果在任何一个任务栈中存在一个该Activity实例,整个任务将会被移动到顶端,并且singleTask Activity上面的每一个Activity都会被销毁掉。如果按下返回键,用户在返回到调用者之前必须经过任务栈中的所有Activity。
& & & 使用该模式的例子就是任何入口点的Activity,例如email客户端的收件箱页面或者是社交网络应用的时间轴。这些Activity不允许有多个实例,所以singleTask模式非常适合。但是你需要明智的使用这种模式,因为Activities可能会在用户不知情的情况下被销毁。
singleInstance
& & & 这个模式和singleTask很接近,系统中只能有一个Activity的实例。不同之处是,持有singleInstance Activity的任务栈只能有一个Activity。如果另一个Activity被singleInstance Activity调用,系统会自动创建一个新的Task来存放新建的Activity。同样,如果singleInstance Activity被调用,也会创建一个任务来存放该Activity。
& & & 从dumpsys提供的信息来看,系统中好像有两个任务,但是只有一个出现在任务管理器中,谁被显示依赖于那个是最近被移动到顶端的。这导致的结果就是,尽管有一个任务仍然在后台工作,但我们无法将其切换到前台。一点意义都没有。。。
& & & 下图展示了当栈中已经存在一些Activity时,调用singleInstance Activity会发生什么:
& & & 但是我们从任务管理器中看到的是如下界面:
& & & 由于这个任务只能有一个Activity,我们不再也不能切换到Task#1了。唯一能做到的办法是重新启动应用,但看起来singleInstance任务反而又会被隐藏在后台。
& & & 不过有解决该问题的办法。就像我们处理singleTask Activity一样,给singleInstance Activity指定一个taskAffinity属性就可以是的任务管理器中出现多个任务。
android:name=&.SingleInstanceActivity&
android:label=&singleInstance launchMode&
android:launchMode=&singleInstance&
android:taskAffinity=&&&
& & & 这种模式很少使用。真正使用到的是Launcher的Activity或者你100%确保只有一个Activity的应用。不管怎样,我建议除非在必要的情况下否则不要使用该加载模式。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:20081次
排名:千里之外
原创:10篇
(1)(1)(1)(5)(1)(1)(1)(2)(7)(1)4135人阅读
基础(11)
singleTop要求如果创建intent的时候栈顶已经有要创建的Activity的实例,则将intent发送给该实例,而不发送给新的实例。(注意是栈顶,不在栈顶照样创建新实例!)
singleTask模式:当intent到来,需要创建singleTask模式Activity的时候,系统会检查栈里面是否已经有该Activity的实例。如果有直接将intent发送给它。
Activity的四种加载模式:
1、standard :系统的默认模式,一次跳转即会生成一个新的实例。假设有一个activity命名为Act1,执行语句:
&startActivity(new Intent(Act1.this,&Act1.class));
后Act1将跳转到另外一个Act1,也就是现在的栈里面有 Act1 的两个实例。按返回键后你会发现仍然是在Act1(第一个)里面。
2、singleTop:singleTop 跟standard 模式比较类似。唯一的区别就是,当跳转的对象是位于栈顶的activity(应该可以理解为用户眼前所 看到的activity)时,程序将不会生成一个新的activity实例,而是直接跳到现存于栈顶的那个activity实例。拿上面的例子来说,当Act1 为&singleTop 模式时,执行跳转后栈里面依旧只有一个实例,如果现在按返回键程序将直接退出。这个貌似用得比较少。
3、singleTask:&singleTask模式和后面的singleInstance模式都是只创建一个实例的。在这种模式下,无论跳转的对象是不是位于栈顶的activity,程序都不会生成一个新的实例(当然前提是栈里面已经有这个实例)。这种模式相当有用,在以后的多activity开发中, 经常会因为跳转的关系导致同个页面生成多个实例,这个在用户体验上始终有点不好,而如果你将对应的activity声明为&singleTask 模式,这种问题将不复存在。不过前阵子好像又看过有人说一般不要将除开始页面的其他页面设置为&singleTask
模式,原因暂时不明,哪位知道的可以请教下。
4、singleInstance: 设置为&singleInstance 模式的 activity 将独占一个task(感觉task可以理解为进程),独占一个task的activity与其说是activity,倒不如说是一个应用,这个应用与其他activity是独立的,它有自己的上下文activity。拿一个例子来说明吧:
现在有以下三个activity: Act1、Act2、Act3,其中Acti2 为&singleInstance 模式。它们之间的跳转关系为: Act1 -- Act2 -- Act3 ,现在在Act3中按下返回键,由于Act2位于一个独立的task中,它不属于Act3的上下文activity,所以此时将直接返回到Act1。这就是singleInstance模式。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:33012次
排名:千里之外
原创:13篇
评论:12条
(3)(1)(1)(1)(2)(1)(1)(1)(2)(1)(1)(4)(1)Android中Activity创建模式singleTask的最佳使用方式 - 推酷
Android中Activity创建模式singleTask的最佳使用方式
Android的创建模式有四种singleTask,standard(默认),singleTop,singleInstance,
在四种创建模式中最长用的应该是默认方式 standard,其次是singleTask,下来是singleTop,最后是singleInstance
这几种创建模式中,往往影响的是Activity的BackStack(回退栈)。
1.标准(standard)模式基本上是后进先出,每次都会重新创建Activity,这点不多说。
2.singleInstance是最少使用的,因为这个Activity的生命周期和应用程序的生命周期是相同的,
销毁也是个问题。在MVC中,Activity类似于Controller,但我们知道基于Servlet的单例效果并不好,
比如出现信息泄露,同步等问题,才出现了后来的SpringMVC,Struts2等使用多例模式。
3.SingleTop, 如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶
(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。
4.singleTask
如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,
会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。
概念说道这里,再来说说SingleTask的使用方式
singleTask保证了在栈中Activity的唯一性,如果被SingleTask标记的Activity处于栈底,站定的Activity发送Intent返回到栈底时,栈中间的Activity会被清除,这个时候被标记过SingleTask的生命周期会响应的做出调整。
onNewIntent-&onStart-&onResume-&.....
这次不会调用OnCreate,但是这里有一个问题,OnNewIntent是被调用了,但是Intent中所保存的数据却仍然还是旧数据,因此需要进一步重写
PS:来一个例子,方便大家理解吧
创建一个一个MainActivity,在Manifest中设置
android:launchMode=&singleTask&
android:name=&com.simple.launchmode.MainActivity&
android:screenOrientation=&portrait& /&
MainActivity.java
* 将activity 的创建模式设置为singletask,
* 使用这个方法可以再其他activity想这个activity发送Intent时,这个Intent能够及时更新
protected void onNewIntent(Intent intent)
super.onNewIntent(intent);
setIntent(intent); //这一句必须的,否则Intent无法获得最新的数据
基本就是这样了,下面我们来说说SingleTask的优化搭配
android:launchMode=&singleTask&
android:taskAffinity=&com.hongkong.stationcontrol.MainActivity&
android:name=&com.hongkong.stationcontrol.MainActivity&
android:screenOrientation=&portrait& /&
android:taskAffinity=&com.hongkong.stationcontrol.MainActivity&
android:taskAffinity相当于一个标签,这个标签是任务名称,SingleTask从字面意思理解是单任务,这里是任务的名称,前面所说的而保持Activity的唯一性只是这个单任务的一个子集,默认情况下任务都是同一个(按照packageName)来设置的,这样他的优势并没有完全发挥,因此要使用
android:taskAffinity=&com.hongkong.stationcontrol.MainActivity&
重新创建一个任务,这样实现了Activity的唯一性的同时,也实现了单任务。
try do it!
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致}

我要回帖

更多关于 intent singletask 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信