Android 图文教学让你彻底理解activity启动模式
我们首先从最简单的开始,
standard
这个模式就是默认的模式,我们都知道 当你用这个模式时,每次发送一个intent,都会生成一个新的实例!
我写一个简单的例子:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.administrator.lanuchmodetest"> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".TestMainActivity"
android:label="@string/title_activity_test_main"
android:theme="@style/AppTheme.NoActionBar"></activity>
</application> </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全部销毁掉。
<activity
android:name=".TestMainActivity"
android:label="@string/title_activity_test_main"
android:launchMode="singleTask"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.TEST_LANUCHMODE" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
好,我们现在就来用图的形式 来解释一下这个过程:
我们假设main 点击以后跳转到testmain
testmain 点击以后 跳转到main2
main2 点击以后 跳转到main3
此时的task 情况为:
此时main3 点击一下 跳转到testmain以后的task情况为:
很符合我们的预期对吧,但是 如果你稍微改一下:
<activity
android:name=".TestMainActivity"
android:label="@string/title_activity_test_main"
android:launchMode="singleTask"
android:taskAffinity=""
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.TEST_LANUCHMODE" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</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 这个单例:
<activity
android:name=".TestMainActivity"
android:label="@string/title_activity_test_main"
android:launchMode="singleInstance"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.TEST_LANUCHMODE" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
看上去 是和singletask 一样,但是如果你打开任务管理器 你会发现:
只有一个!
并且当你从任务管理器 进入到这个界面时,你点返回 是无法回到main的!
所以说这种情况 虽然是2个task ,但是系统在任务管理器只显示一个!
并且返回回不到前面一个acitivity,这样的体验非常糟糕 一定要慎用!
当然解决方法也有,只要加上taskaffinity属性即可!
加上以后 你再打开任务管理器 就是:
一切正常。
不过还是想多说一句 单例模式 尽量慎用,尤其是不带taskaffinity属性的,据我目前看过的源码里面 应该只有
某些手机rom里的lanucher 会用这个属性,其他任何app中 我都没有见过用这个属性的。所以大家也一定要慎用!
因为会给用户造成困惑!
Android 图文教学让你彻底理解activity启动模式的更多相关文章
- Android Activity 启动模式详解
最近有群里的朋友问我 Activity的四种启动模式分别是什么意思? 当初因为项目比较忙,草草的解释了下, Api文档中说的也只是一般,在这里就小记一下吧,以便有更多的朋友对Activity启动模式了 ...
- 【转】Android总结篇系列:Activity启动模式(lauchMode)
[转]Android总结篇系列:Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些 ...
- 《转》深入理解Activity启动流程(三)–Activity启动的详细流程2
本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...
- 《转》深入理解Activity启动流程(三)–Activity启动的详细流程1
本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...
- 《转》深入理解Activity启动流程(二)–Activity启动相关类的类图
本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 在介绍Activity的详细启动流程之前,先为大家介绍Act ...
- 《转》深入理解Activity启动流程(一)–Activity启动的概要流程
本文原创作者:Cloud Chou. 原文地址:http://www.cloudchou.com/android/post-788.html Android中启动某个Activity,将先启动Acti ...
- AndroidのActivity启动模式
Activity启动模式 .概念 Activity启动模式定义了Activity启动的规则,它决定着Activity的实例创建与重用与否 .属性 Activity的启 ...
- 深入理解Activity启动流程(三)–Activity启动的详细流程2
本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--A ...
- 深入理解Activity启动流程(二)–Activity启动相关类的类图
本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 在介绍Activity的详细启动流程之前,先 ...
随机推荐
- (转)两分钟彻底让你明白Android Activity生命周期(图文)!
转自: http://blog.csdn.net/android_tutor/article/details/5772285 大家好,今天给大家详解一下Android中Activity的生命周期,我在 ...
- HDU5596/BestCoder Round #66 (div.2) 二分BIT/贪心
GTW likes gt Memory Limit: 131072/131072 K (Java/Others) 问题描述 从前,有nn只萌萌的GT,他们分成了两组在一起玩游戏.他们会排列成一排 ...
- ubuntu系统使用minicom终端操作说明
http://blog.chinaunix.net/uid-22030783-id-3350834.html 在linux下,使用minicom作为串口终端工具,默认的串口设备是/dev/ttyS0, ...
- 什么是边界扫描(boundary scan)?
边界扫描(Boundary scan )是一项测试技术,是在传统的在线测试不在适应大规模,高集成电路测试的情况下而提出的,就是在IC设计的过程中在IC的内部逻辑和每个器件引脚间放置移位寄存器(shif ...
- Android:开发环境
一.JAVA SDK(JDK)的安装 http://www.cnblogs.com/tinyphp/p/3664598.html 二.ADT-Bundle 包含了Eclipse.ADT插件和SDK T ...
- MyBatis学习总结_06_调用存储过程
一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存储过程 1 create table p_user( 2 id int primary key auto_ ...
- Android 实现Path2.0中绚丽的的旋转菜单
上图先: 那么下面开始吧~ 首先,将整个菜单动画分解开来. 1. 一级菜单按钮的旋转动画2个,十字和叉叉状态的转换. 2. 二级菜单按钮的平移动画2个,弹簧效果的in和out ...
- Python得到前面12个月的数据,Python得到现在时间 前一年的数据,
#Python 实现得到现在时间12个月前的每个月 # 假设现在的时间是2016年9月25日 #得到现在的时间 得到now等于2016年9月25日 now = datetime.datetime.no ...
- 2-Medium下的MultipleCommandAssembly
1.首先创建一个控制台项目 2.添加引用[红色的都是将项目添加为引用,其中蓝色的log4net是直接从源代码下的Reference文件夹下引用的dll] 3.写代码 1)首先将config配置好[ht ...
- 【转】对Android开发者有益的40条优化建议
下面是开始Android编程的好方法: 找一些与你想做事情类似的代码 调整它,尝试让它做你像做的事情 经历问题 使用StackOverflow解决问题 对每个你像添加的特征重复上述过程.这种方法能够激 ...