金鞍玉勒寻芳客,未信我庐别有春。这篇文章主要讲述android launchMode理解以及应用场景相关的知识,希望能为你提供帮助。
在我们写应用的时候,
常常涉及多个activity组件之间的跳转。比如说某个资讯的页面中,
点击下一篇资讯跳转相同的页面,
只有页面的数据不一样。一般情况下我不会注意launchMode 这个属性,
只会使用默认的,
这样会产生大量重复的activity。那是因为之前不了解,所以特此研究学习。
1.如何指定launchMode 基本上我们可以直接指定一个launchMode属性在androidManifest.xml 文件中
<
activity
android:name=
"
.views.MainActivity"
android:screenOrientation=
"
portrait"
android:launchMode=
"
singleTop"
/>
存在4中类型的launchMode
文章图片
2.standard 模式介绍 这是默认模式, 每次激活Activity时都会创建Activity实例, 并放入任务栈中。
activity设置为这个模式的行为是一个新的活动, 每一个意图发送,将总是被创建的工作分开。想象一下, 如果有10的意图去写邮件, 应该有10个活动的开展为每一个单独的意图。因此, 有可能是一个无限数量的这种活动在一个设备启动。
2.1 5.0 版本之前
这种activity将被创建, 并放置在堆栈的顶部, 在同一个task, 发送一个Intent。
文章图片
下面的一个图片显示当我们将一个图像分享到一个标准的activity时会发生什么。它将被堆叠在同一个任务中, 虽然他们是从不同的应用程序。
文章图片
这是你将在任务管理器中看到的。( 可能有点奇怪)
文章图片
如果我们换到另一个应用程序, 然后再切换回Gallery, 我们仍将看到顶上画廊的任务launchMode标准的地方。因此, 如果我们需要做任何与Gallery相关的操作, 我们必须完成当前activity的事情或者关闭当前的activity, 才可以回到原来的地方。
2.2 5.0版本之后
如果这些活动都来自同一个应用程序, 它能够像5.0之前一样, 堆叠的任务
文章图片
但是在某些情况下, 我们发送的Intent 来自不同的intent,新的task将被创建, 新创建的activity将被放置在下面的根activity中。
文章图片
下面是我们重任务管理器中看到的和5.0之前是有区别的
文章图片
这是因为任务管理系统的改进Lollipop使它更有意义。Lollipop, 你可以切换回画廊, 因为它们是不同的任务。你可以发射另一个意图, 一个新的任务将被创建, 以服务一个与前一个相同的意图。
文章图片
2.3 应用场景举例
这种activity的一个例子是一个组成电子邮件activity或社交网络的状态张贴activity。如果你考虑一个可以单独工作的活动, 为一个单独的意图服务。
举例引用:
AlarmClock uses standard. The user can launch multiple instances of this activity and these instances can be part of any task and anywhere in the activity stack. As a fairly simple application it doesn’t really demand tight control of its activity闹钟的使用 standard。用户可以启动此activity的多个实例, 这些实例可以是任何任务的一部分, 也可以是活动堆栈中的任何地方的一部分。作为一个相当简单的应用, 它并不真的需要它的activity的严格控制
3.singleTop 模式介绍 singleTop模式。它的作用几乎和standard一样。唯一不同的是, 如果已经存在在栈顶在对方的任务一个同类型的活动实例, 不会有任何新的activity创造, 而是被发送到一个存在的activity实例通过onNewIntent() 方法的意图, 即会重用该实例调用当前activity的onNewIntent() 方法。
文章图片
在singleTop模式, 对于新的Intent, 你要负责onCreate() 和 onNewIntent() 来控制使它适用于所有的情况。
3.1 应用场景举例
这个模式的一个示例用例是一个搜索功能。我们想创造一个搜索框, 它会带你到一个SearchActivity看到搜索结果。为了更好的用户体验, 我们通常总是把一个搜索框, 在搜索结果页面以及让用户做另一个搜索无压回。
现在想象一下, 如果我们总是推出服务新的搜索结果的新searchactivity, 10次搜索将产生10个新activity。这将是非常奇怪的, 当你按下回来, 因为你必须要10次, 通过这些搜索结果activity, 以获得回你的根activity。相反, 如果在栈顶 searchactivity, 我们最好送一个Intent的一个存在的activity实例, 让它更新搜索结果。现在只会有一个searchactivity放在栈顶, 你可以简单地按下按钮就回一次回到以前的活动。现在有更多的意义。
反正singleTop 作用相同的任务栈。如果你期望一个Intent被发送到一个存在的活动放置在任何其他任务的顶部, 我必须让你失望, 说它不工作。如果Intent是从另一个应用程序发送到singleTop activity, 新的activity将推出在同一方面作为standard launchMode。
注意: 5.0之前: 放在对方的任务, 5.0以及之后( Lollipop) : 一个新的任务被创建。举例引用:
BrowserBookmarksPage uses singleTop. While there can be multiple instances of this activity, if there is already one at the top of the task’s activity stack it will be reused and onNewIntent() will be called. This way you only have to hit back once to return to the browser if the bookmarks activity is started multiple times.浏览书签页面使用singleTop。虽然有可能是这一活动的多个实例, 如果已经有一个在任务栈顶的活动将被重用和onnewintent()将被调用。这样, 你只需要返回一次返回到浏览器, 如果书签activity是开始多次。
4.singleTask 模式介绍 这种模式和 standard singleTop完全不同。采用singleTask launchMode 的activity是允许在系统中只有一个实例( 又名Singleton) 。如果系统中有一个存在的活动实例, 整个任务将实例将被移动到顶部, Intent将通过onnewintent()方法交付。否则, 新的activity将被创建并放置在适当的任务中。
4.1 在同一个应用中
如果没有在系统中还存在singleTask活动实例, 新一将要建立简单的放在栈顶在同一个任务。
文章图片
但如果有一个存在的singleTask activity实例放在上面, 会自动地破坏(以恰当的方式 生命周期触发)其他的activity, 让该实例出现在栈顶。同时, 一个Intent是通过的onnewintent()方法送到singleTask activity。
文章图片
在用户体验上没有一个很好的感觉, 但它是这样设计的…
The system creates a new task and instantiates the activity at the root of the new task.但从实验中, 它似乎不工作。单一任务活动仍栈顶上的任务的活动堆栈。从中我们可以看到什么dumpsys活动命令显示。
注意: 系统创建一个新任务并实例化活动新任务的根。
文章图片
如果你想让一个活动就像描述singleTask文档: 创建一个新的任务, 把活动作为一根活动。你需要指定的taskAffinity属性为singleTask这样的活动。
文章图片
下面是启动SingleTaskActivity 的结果示例
文章图片
文章图片
考虑是否使用taskAffinity的行为, 这是你的工作。4.2 与另一个应用合作
一旦一个 Intent 是从另一个应用程序发送, 并且没有在系统中创建的任何活动实例, 新的任务将创建一个新创建的活动作为一个根活动。
文章图片
文章图片
除非有一个应用程序, 是一个拥有调用singleTask activity存在的任务, 创造了新的活动会放在上面。
文章图片
如果有任何任务存在的活动实例, 整个任务将被移动到顶部和每个单独的activity在singleTask activity上的将会被销毁按照正常的生命周期。如果按下后退按钮, 用户必须在返回到调用方任务之前通过堆栈中的活动进行。即先关闭图中task#1 中的activity,再回到task#2.
文章图片
4.3 应用场景示例
这种模式的一个示例用例是任何一个入口点活动例如电子邮件客户端的收件箱页面或社交网络的时间轴。无论如何, 你必须明智地使用这个模式, 在这种模式下活动可能会被破坏。
BrowserActivity uses singleTask. There is only one browser activity at a time and it doesn’t become part tasks that send it intents to open web pages. While it might return to whatever most recently launched it when you hit back it is actually fixed at the bottom of its own task activity stack. It will share its task with activities that it launches like bookmarksbrowseractivity使用singleTask。只有一个浏览器的活动的时间, 它不成为一部分的任务, 把它试图打开网页。虽然它可能会返回到任何最近推出的它, 当你回击它实际上是固定在其自己的任务活动栈的底部。它将分享它的任务与活动, 它推出像书签.
5.singleInstance 模式介绍 这种模式是相当接近singleTask, 单个activity实例可以存在于系统中。不同的是任务举行这次活动, 只能有一个活动。如果这种活动调用另一个活动, 一个新的任务将被自动创建, 以放置新的活动。同样, 如果singleInstance活动被被调用, 新的任务将会被创建放置这个activity。
无论如何, 结果是相当奇怪的。从dumpsys提供的信息, 它在系统中有两个任务, 但只有一个出现在任务管理器中最新的一个决定, 移动到顶部。因此, 虽然有一个任务, 仍然在后台工作, 但我们不能切换到前台。根本没有任何意义。
这是singleInstance活动被调用同时一个activity已经存在在task 中。
文章图片
但是在任务管理器中看不到新的task
文章图片
由于这项任务可能只有一个活动, 我们无法切换回任务# 1了。这样做的唯一方法是重新启动的应用程序, 但看来singleInstance任务将被隐藏在后台。
简单地分配taskAffinity属性到singleInstance活动使任务管理多个任务。
<
activity
android:name=
"
.SingleInstanceActivity"
android:label=
"
singleInstance launchMode"
android:launchMode=
"
singleInstance"
android:taskAffinity=
"
"
>
这样将看到被隐藏的task
文章图片
5.1 应用场景示例
AlarmAlert uses singleInstance. Only one alert activity at a time and it is always its own task. Anything it launches (if anything) becomes part of its own new taskalarmalert使用singleInstance。只有一个警报活动在一个时间, 它总是自己的任务。它启动的任何东西( 如果有的话) 成为它自己的新任务的一部分
这种模式很少被使用。一些真正的用例是一个用于启动或应用程序的活动, 你是100%肯定只有一个活动。总之, 我建议你不要使用这种模式, 除非它是真的有必要。
6.Intent FlagslaunchMode是规定你自己的Activity启动的行为模式, 而Intent.Flag是你期望由你启动的其他的Activity是什么样的行为模式
除了分配启动模式直接在AndroidManifest.xml, 我们也能够通过所谓的意图标志更多的行为分配, 例如:
Intent intent =
new Intent(StandardActivity.this, StandardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
7.总结以及参考资料7.1 总结
[1] standard 模式
这是默认模式, 每次激活Activity时都会创建Activity实例, 并放入任务栈中。
[2] singleTop 模式
如果在任务的栈顶正好存在该Activity的实例, 就重用该实例( 会调用实例的 onNewIntent() ), 否则就会创建新的实例并放入栈顶, 即使栈中已经存在该Activity的实例, 只要不在栈顶, 都会创建新的实例。
[3] singleTask 模式
如果在栈中已经有该Activity的实例, 就重用该实例(会调用实例的 onNewIntent() )。重用时, 会让该实例回到栈顶, 因此在它上面的实例将会被移出栈。如果栈中不存在该实例, 将会创建新的实例放入栈中。
[4] singleInstance 模式
在一个新栈中创建该Activity的实例, 并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中, 任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用, 不管谁激活该 Activity 都会进入同一个应用中。
最后, 资料什么的都看完了, 学习到了很多。最近在写项目会用到launchMode,将以前模糊不明白的地方, 搞懂一些。磨刀不误砍柴工说的很对, 所以先看资料学习, 再通过项目练手加深印象。
7.2 参考资料
1.Understand Android Activity’s launchMode: standard, singleTop, singleTask and singleInstance
2.http://stackoverflow.com/questions/2626218/examples-for-android-launch-modes
3.基础总结篇之二: Activity的四种launchMode
4. android launchmode(四种启动模式)应用场景及实例
【android launchMode理解以及应用场景】5.Android activity launchMode与Intent.Flag关系
推荐阅读
- Android(IPC之AIDL的学习和总结)
- 安卓开发之基于AccessibilityService实现聊天机器人对其他应用的调起
- Android开发学习——Android项目的目录结构
- Android圆角图片和圆形图片实现总结
- Android中的布局动画
- Android-异步任务-AsyncTask
- Android开发使用TotalControl调试遇到的问题(备注)
- Android Cordova 插件开发之编写自定义插件
- Android中Xposed框架篇---利用Xposed框架实现拦截系统方法