Android 图文教学让你彻底理解activity启动模式

我们首先从最简单的开始,

standard

这个模式就是默认的模式,我们都知道 当你用这个模式时,每次发送一个intent,都会生成一个新的实例!

我写一个简单的例子:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.example.administrator.lanuchmodetest">
 4
 5     <application
 6         android:allowBackup="true"
 7         android:icon="@mipmap/ic_launcher"
 8         android:label="@string/app_name"
 9         android:supportsRtl="true"
10         android:theme="@style/AppTheme">
11         <activity
12             android:name=".MainActivity"
13             android:label="@string/app_name"
14             android:theme="@style/AppTheme.NoActionBar">
15             <intent-filter>
16                 <action android:name="android.intent.action.MAIN" />
17
18                 <category android:name="android.intent.category.LAUNCHER" />
19             </intent-filter>
20         </activity>
21         <activity
22             android:name=".TestMainActivity"
23             android:label="@string/title_activity_test_main"
24             android:theme="@style/AppTheme.NoActionBar"></activity>
25     </application>
26
27 </manifest>

对于这个app来说,MainActivity 是他的第一个默认启动的acitivity,TestMainActivity是第二个activity,MainActivity上有一个按钮 点击以后就发送intent会跳转到TestMainActivity上,

我重写了TestMainActivity的onBackPressed方法,使得在这个activity上按返回键时 不会走系统自动销毁的方法,而是发送intent到MainActivity上来启动MainActivity。

当我们重复了几次这个动作以后,在命令行上输入 adb shell dumpsys activity activities ,可以得到:

你看 这个就能清晰的看出来 当前我们这个app 有一个task栈,这个栈里所有存在的activity都在这个task里,有很多重复的。

当然了这个是最简单的情况,我们现在考虑 如果是外部一个app 来启动我们这个app里的TestMainActivity是什么情况?

现在我就来写一个outerlanuchmodetest 的app 来启动我们lanuchmodetest 这个app里的 TestMainActivity 看看是什么效果

(这里代码太简单略了),写完以后运行 命令


你会发现 TestMain虽然是定义在lanuchmode这个app里的但是 如果外部app启动了他,他还是会在那个外部app里的task!

于此同时,在我这个低于5.0(4.3版本)的模拟器里,你打开最近启动app的列表 你会发现是这样的:

同时我们点进去以后 会发现 我们必须点一次返回键才能回到我们的Outer这个app自己的界面。

singleTop

这个稍微有点难度,比上面稍微复杂点。实际上singletop和standrd 基本上差不多,也是可以有多个activity实例的,

唯一的不同在于:

如果调用的 目标activity 位于调用者的task的 栈顶,则不会创建新的实例,而是使用当前的这个activity 并调用onNewIntent方法。

目标 activity 位于调用者的task的栈顶,很多人理解不了,其实翻译过来就是自己启动自己。比如很多app里的搜索结果界面

就是这样的,你每次搜索 其实都是调用onNewIntent。设想一下,如果不用这个singleTop,那你搜索100次 不就有100个搜索页面了

那你要回到上个页面 得返回100次。

下面来做一个app,这个app的testMainActivity页面 有个按钮 点击他就启动自己,我们看看会发生什么?

我们可以看出来,当第一次启动这个testmain的时候 onNewIntent是不走的 走的是onCreate ,以后每发送一个

启动这个页面的intent,onCreate都不会走了 都是走的onNewIntent。

现在看看task里的情况:

当然你要是从另外一个app去启动的话 ,因为另外一个app 有自己的task 所以当然是可以有2个testMainActivity实例的:

singleTask

这个相对于singetop来说,这个又要复杂一些。

用这个启动模式的,activity 在整个系统中都只有1个!注意是整个系统 而不是某个task 这是和top最大的区别。

如果这个实例存在 那就会由onNEWINTENT来 接受这个intent。这一点倒是和top一样。

并且 会把他前面的 activity全部销毁掉。

 1  <activity
 2             android:name=".TestMainActivity"
 3             android:label="@string/title_activity_test_main"
 4             android:launchMode="singleTask"
 5             android:theme="@style/AppTheme.NoActionBar">
 6             <intent-filter>
 7                 <action android:name="android.intent.action.TEST_LANUCHMODE" />
 8
 9                 <category android:name="android.intent.category.DEFAULT" />
10             </intent-filter>
11         </activity>

好,我们现在就来用图的形式 来解释一下这个过程:

我们假设main 点击以后跳转到testmain

testmain 点击以后 跳转到main2

main2 点击以后 跳转到main3

此时的task 情况为:

此时main3 点击一下 跳转到testmain以后的task情况为:

很符合我们的预期对吧,但是 如果你稍微改一下:

 1  <activity
 2             android:name=".TestMainActivity"
 3             android:label="@string/title_activity_test_main"
 4             android:launchMode="singleTask"
 5             android:taskAffinity=""
 6             android:theme="@style/AppTheme.NoActionBar">
 7             <intent-filter>
 8                 <action android:name="android.intent.action.TEST_LANUCHMODE" />
 9
10                 <category android:name="android.intent.category.DEFAULT" />
11             </intent-filter>
12         </activity>

你看 我们加了一个taskAffinity属性,这个时候我们再重复一遍上述那个过程的第一步 你就会发现,此时的task情况是这样的:

你看,这里 我们发现 虽然都是一个应用内的activity互相启动 但是当你加了这个属性以后,我们由main 跳往testmain的时候

是新开的一个栈!而不是原来的main自己的那个栈了!当我们从main3 跳往testmain的时候:

依旧是如此! 所以要注意这个属性 对singtask的影响!

包括你打开任务管理器都是这样的:

刚才我们讲的是singtask的 应用内之间 的情况,现在来讲一下 应用外跳转的情况!

注意当跨应用跳转时,taskAffinity 属性就不影响singetask了。加不加都一样(有兴趣的同学可以自己试试)

当跨应用 跳转时 情况如下:

1.当目标app进程不在的时候:

你看,此时我们还在活动的activity 就是系统的lanucher 和我们自己的outerlanuchmode。

此时如果启动lanuchmode 这个app里的testmain,那么就会:

你看 此时系统task 就是这样的,

所以针对这种情况 结论就是:当目标activity所属的app没有启动,并且activity属性属于singetask的时候,

调用者 启动这个acitivity的结果就是 必定会在另外一个task里!

2.第二种情况:

目标activity所属的app 已经启动了,但是目标activity还没有启动

此时如果点击启动目标activity

结果也很明了,当然还有另外一种复杂的情况,如果目标activity已经有了testmainactivity 存在 会怎么样,这里就不写了,

有兴趣的同学可以自己写个demo 看下task的情况。

singleInstance

最后看一下 这个单例模式,其实这个最简单,就是无论什么时候,这个属性的activity 都是自己单独占据一个栈的。

并且和前面的singleTask类似,在系统中 只有一份!

比方说我们从main 跳转到testmain 这个单例:

 1   <activity
 2             android:name=".TestMainActivity"
 3             android:label="@string/title_activity_test_main"
 4             android:launchMode="singleInstance"
 5             android:theme="@style/AppTheme.NoActionBar">
 6             <intent-filter>
 7                 <action android:name="android.intent.action.TEST_LANUCHMODE" />
 8
 9                 <category android:name="android.intent.category.DEFAULT" />
10             </intent-filter>
11         </activity>

看上去 是和singletask 一样,但是如果你打开任务管理器 你会发现:

只有一个!

并且当你从任务管理器 进入到这个界面时,你点返回 是无法回到main的!

所以说这种情况 虽然是2个task ,但是系统在任务管理器只显示一个!

并且返回回不到前面一个acitivity,这样的体验非常糟糕 一定要慎用!

当然解决方法也有,只要加上taskaffinity属性即可!

加上以后 你再打开任务管理器 就是:

一切正常。

不过还是想多说一句 单例模式 尽量慎用,尤其是不带taskaffinity属性的,据我目前看过的源码里面 应该只有

某些手机rom里的lanucher 会用这个属性,其他任何app中 我都没有见过用这个属性的。所以大家也一定要慎用!

因为会给用户造成困惑!

时间: 2024-10-17 16:25:52

Android 图文教学让你彻底理解activity启动模式的相关文章

深入理解Activity启动模式

今天看到这个,觉得还不错,于是乎收藏下 作者原创连接    共分3篇: 深入理解Activity启动模式(一)–Activity与进程,线程的关系 深入理解Activity启动模式(二)–Activity,回退栈,Task之间的关系 深入理解Activity启动模式(三)–Activity启动模式特点 概述 Android官网介绍Activity的启动模式时比较含糊,介绍Application,Activity,Task,Process,Thread等概念以及它们之间的关系时,也没有说得清楚.大

《Android深入透析》之 浅析Activity启动模式

摘要 Activity的启动模式是一个既基础又容易忽视的问题,但是这个问题有个深刻的认识,对程序员写一个稳定高效的Android程序帮助很大,今天,在B哥引导下,我们对Activity启动模式.Intent Flags做了一番很好的探究,可以这么说,如果你不熟悉或了解Activity的启动模式或者Flags怎么用,今后你在实际开发中,绝对会被困扰,回过头来重新学习这一节,举个例子:有人写出的客户端,为什么崩溃了,底下仍然有一个乃至N个该应用的界面,如果你熟读并且准确理解此章,必然不会出此错误.

带你深入理解Activity启动模式(LaunchMode)

我们知道默认情况下,当我们多次启动同一个activity时,系统会创建多个实例并把他们一个个放入任务栈,当我们按back键,这些activity又会一个个退出.在讲activity的launchmode之前,我们有必要了解下"任务栈(Task Stack)"这个概念.在Android中是使用任务(Task)来管理Activity的,任务就是存放在栈里面的Activity的集合,这个栈就是称为任务栈. 一,Activity的LaunchMode 明白任务栈的概念后,我们再来了解Activ

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

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

Android Activity启动模式

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

Android总结篇系列:Activity启动模式(lauchMode)

本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些理解,在此感谢原作者. 文章地址: http://blog.csdn.net/liuhe688/article/details/6754323 ------------------------------------------------------------------------------------------------- launchMode在多个Activit

AndroidのActivity启动模式

Activity启动模式      .概念    Activity启动模式定义了Activity启动的规则,它决定着Activity的实例创建与重用与否    .属性   Activity的启动模式在menifest.xml中的<activity>标签中设置,属性为launchMode    .分类     Activity的启动模式分为四类: standard . singleTop . singleTask . singleInstance     .备注   Android采用Task来

我对standard、singleTop、singleTask和singleInstance四种Activity启动模式的理解

之前自学android的时候,单从视频和书本上对这四种启动模式仅仅有了初步的字面上的理解.最近实战了下,也对这四种启动模式有了比较清晰的概念. 首先说下什么是Activity,按照我的理解,我们在手机上看到的每一个页面都是一个Activity,包括系统的桌面,也是一个Activity. 要启动一个Activity有四种模式:standard(标准启动模式).singleTop.singleTask.singleInstance. 注: Aty1_1和Aty2_1为两个不同的Activity,At

【Android基础】Activity启动模式以及Intent Flags 与 栈 的全面解析

Android开发的过程中,Intent是我们最常用Android用于进程内或进程间通信的机制. Intent主要用于2种情景下:发起意图 .广播 其底层实现原理不在此篇文章的讨论范围,以后会陆续更新上的. 下面我就根据近期学习,总结记录下Activity启动模式 及 Intent Flags 与 栈 的关联分析. 1.首先我们先搞清楚什么是栈: 栈是一种常用的数据结构,栈只允许访问栈顶的元素,栈就像一个杯子,每次都只能取杯子顶上的东西,而对于栈就只能每次访问它的栈顶元素,从而可以达到保护栈顶元