Activity启动模式的深入分析

网上关于Activity启动模式的文章非常多,但是看起来都千篇一律,看完之后我们都能理解这4种启动模式,不过官方api对singleTask这个启动模式解释有些争议,导致我其实并没有真正理解这几种模式,特别是对实际开发到底怎么用还是一知半解,于是花了一天时间好好研究这4种启动模式。

首当其冲应该知道Task的概念,它是我们一系列操作连贯跳转activity形成的一个activity栈,后进先出也就是说当前看到的activity在最上面,关于Task的概念老罗一篇博客说的比较清楚,引自老罗博客:

“在解开这个谜之前,我们先来简单了解一下在Android应用程序中,任务(Task)是个什么样的概念。我们知道,Activity是Android应用程序的基础组件之一,在应用程序运行时,每一个Activity代表一个用户操作。用户为了完成某个功能而执行的一系列操作就形成了一个Activity序列,这个序列在Android应用程序中就称之为任务,它是从用户体验的角度出发,把一组相关的Activity组织在一起而抽象出来的概念。”

为什么要设置不同的启动模式呢?是为了更好的复用activity,带来两个好处一是节约系统资源,二是避免糟糕的用户体验,比如当前已经存在这个activity,除了standard其他三种模式就会去查找是否存在activity,如果存在就不再执行onCreate()去new而是直接把那个activity显示在栈顶并调用onNewIntent()。singleTop
 singleTask singleInstance的区别就是查找的范围不一样,singleTop最小只会在当前task的栈顶去看(单应用级别),而singleTask不仅在当前task还会在其他的Task查找(半应用半系统级别),而singleInstance只会去其他task查找,因为有singleInstance的activity都是独占一个task,你的当前task不可能含有这个activity!那么广义上也可以认为singleInstance是系统全局的!

所以可以这么理解4种启动模式,更清晰:

standard    不限实例个数。只要启动就会在当前task最上面new一个实例,可以叠加,注意它不会创建新的Task

singleTop
  在当前栈顶(Top)只有一个实例。
比如自己启动自己只会是同一个实例,不过这种需求貌似很少,还有一种就是一个界面打开着,被外部service或者广播反复启动,比如新闻客户端打开着接受推送打开界面。那么你在自己的acticityA打开另外应用的activityB,这个B设置成singleTop就是无意义的,因为它只判断当前A的Task,so我前面把它理解成单应用级别。(当然更严谨一点只限activity因为service或者广播可以是其他应用的)

singleTask  在所有Task只有一个实例。这个启动模式争议最多特别是官方文档说:"singleTask"会在新的任务中运行,并且位于任务堆栈的底部。很多人不认同,老罗也写了博客来解释,其实官方文档没错,因为singleTask一般要跟android.intent.action.MAIN和android.intent.category.LAUNCHER一起配置,作为程序入口他当然是栈底,会在新的任务启动是指当前Task没有这个activity的情况,而singleTask的正确使用就应该满足这种情况,所以官网文档的解释建立在我们正确使用这个属性的基础上,如果你非不把singleTask和android.intent.action.Main  category.LAUNCHER一起配置,那另当别论但是无意义。

那么先说singleTask的启动逻辑:1. 如果当前task有这个activity我们直接把它上面所有activity clear掉,它就显示出来了。2. 如果当前task A没有但是其他task B(一般是其他应用的task)有这个activity,我们直接把task B整个搬到task A上面,并且把task B上面的多余activity clear掉,当然若这个activity就在task B的顶部就不需要咯,搬过来就显示了,此时按回退键就会从task B开始一个个往task A回退  3. 若所有task都没有这个activity就会new一个实例在新的task B放在task A上面(注意这里new了Task)。按照这个逻辑思考一下,我们把浏览器的首页设置为singleTask并且加上Main和LAUNCHER的属性,一启动它就在栈底了,用了一段时间浏览器导致大量activity堆积,我们只要回到首页,因为它是singleTask那么上面的activity都被clear,此时用户点后退就退出整个应用了,很舒服人性化的操作。还有,我们从别的应用比如微信想访问网页就会打开这个浏览器首页,因为它肯定在栈底那我们访问完了直接后退就能回到我们自己应用,试想一下这个首页activity不和Main&LAUNCH一起,那他下面肯定有浏览器其他activity堆积,我们访问完了点后退就会看到浏览器之前未关闭的activity,多次后退才回到微信,很奇怪不是吗。而且浏览器首页是笨重的界面,如果不设为singleTask我们从其他应用打开就得new很多个,浪费资源。包括联系人APP首页也是一样的道理。

                   singleInstance  在所有Task只有一个实例,并且这个task只有它一个activity存在。这个用的少一些,比如在接听电话的那个界面InCallUi,就把他单独放在一个task,不与任何其他activity共存,因为没必要,接电话的界面还能往哪跳?
比如闹钟响铃提醒界面,都是些和其他activity无关联不需跳转的界面,也就是独立性很强的activity。

总结一下:可以把前两种模式归在一起学习,一般在单个应用开发,这个界面不会被其他应用启用的情况,而且跳转频繁用singleTop,不怎么跳转而且activity较少用标准也可以。要是系统级的比如浏览器,联系人,电话,短信就要考虑后两种模式了,别人写的应用场景,参考一下:

singleTop适合接收通知启动的内容显示页面。

例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。

singleTask适合作为程序入口点。

例如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。

singleInstance适合需要与程序分离开的页面。

例如闹铃提醒,将闹铃提醒与闹铃设置分离。

singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) ->
C,完全退出后,在此启动,首先打开的是B。

参考文档:     http://blog.csdn.net/luoshengyang/article/details/6714543

https://developer.android.com/guide/components/tasks-and-back-stack.html

时间: 2024-08-26 13:35:17

Activity启动模式的深入分析的相关文章

深入Activity,Activity启动模式LaunchMode完全解析

转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53221384 本文出自[DylanAndroid的博客] 深入Activity,Activity启动模式LaunchMode完全解析 在平时的开发中,我们可能会了解到Activity的任务栈还有Activity的启动模式.那么Activity的启动模式都分别是怎么样的呢?如果设置了这些启动模式对任务栈有事么影响 ,还有就是这么启动模式在实际的开发中有什么应用呢?这里用图例和d

Android中Activity启动模式详解,可以控制程序按home键后进来还会调用一个自己不喜欢的界面

其实这是很简单的一个问题.但是这还是要对android中activity的启动模式有相当的理解才行,当点击home键的时候,懂Android的人都知道,他会把当前activity放到后退栈中, 栈(Stack)又称堆栈,它是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算.人们把此端称为栈顶,栈顶的第一个元素被称为栈顶元素,相对地,把另一端称为栈底.向一个栈插入新元素又称为进栈或入栈,它是把该元素放到栈顶元素的上面,使之成为新的栈顶元素:从一个栈删除元素又称为出栈或退栈,它是把栈

activity启动模式之singleTop

activity启动模式之singleTop 一.简介 二.设置方法 在AndroidManifest.xml中将要设置为singleTop启动模式的页面进行配置 <activity android:name="activityLaunchSingleTop.ActivityB2" android:launchMode="singleTop"></activity> 三.代码实例 效果图: 代码: activityLaunchSingleTo

Activity启动模式

在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. Android总Activity的启动模式分为四种: Activity启动模式设置: <activity android:name=".MainActivity" android:launchMode="standard" /> Activity的四种启动模式:

activity启动模式笔记

activity启动模式的逻辑主要在startActivityUncheckedLocked()函数中,现在来看下这个函数. final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doRe

Android Activity启动模式

在Android的联机文档中,有对Activity的简单介绍,现在通过编写代码对Activity的启动模式做一个深入的理解.在配置文件AndroidManifest.xml中,activity元素的android:launchMode属性用来配置对应Activity的启动模式,目前有以下四种启动模式:1.standard2.singleTop3.singleTask4.singleInstance如果不对Activity设置启动模式,默认就是standard模式 一.standard 请看以下代

Activity启动模式 及 Intent Flags 与 栈 的关联分析

   在学习Android的过程中,Intent是我们最常用Android用于进程内或进程间通信的机制,其底层的通信是以Binder机制实现的,在物理层则是通过共享内存的方式实现的.     Intent主要用于2种情景下:(1)发起意图  (2)广播     它的属性有:ComponentName,action,data,category,extras,flags等,通常情况下,进行Intent的匹配涉及到3个属性:Action,Data,Category.这些东西都需要了解才能对它有个深入的

activity启动模式之standard

activity启动模式之standard 一.简介 就像一只叠加在栈中 如果退出,就一个个退出,其实就是我们自己用手机的那种感受 二.代码实例 activityLaunchStandard.MainActivity 1 package activityLaunchStandard; 2 3 4 5 6 import com.example.activityLaunchStandard.R; 7 8 import android.app.Activity; 9 import android.co

android:process结合activity启动模式的一次实践

会有这样的场景,一个应用崩溃了,而导致的该应用崩溃的原因是,该应用占用的内存大小超过了系统分配给它的最大堆大小.对象的分配,是发生在堆(heap)上面的,系统分配给每个应用的最大堆大小是固定的. 假设,出现这种情况了,你的应用再启动一个activity,就导致了你的应用崩溃了,你的应用使用的内存超过了系统分配的最大堆大小.那么,这个时候,可以采取做法是,优化算法之类的,但是,假设,你优化了,但是,依然出现这个问题. 那么,可以采取这种做法:让被启动的Activity运行在一个新的独立进程中,这样