浅析Activity启动模式
四种启动模式
standard(默认模式)
举个栗子
- 同一App中默认模式下的Activity启动情况?
下面来看个例子,Activity1 启动 Activity2,Activity2 再启动 Activity1。下面是输出的日志:
com.demo.activity.Activity1@61b47ba
com.demo.activity.Activity2@16908e9
com.demo.activity.Activity1@e6cbe2
根据上面的输出日志,可以知道每次创建的Activity都是一个新的实例。
- App2启动App1中默认模式下的Activity的情况?
先启动App1,再启动App2,App2启动App1中的Activity2:
D/ActivityOne: com.demo.activity.Activity1@2946b4d onCreate taskId: 62
D/ActivityTwo: com.demo.activity.Activity1@2946b4d onCreate taskId: 63
D/ActivityOne: com.demo.activity.Activity2@1a7626a onCreate taskId: 63
从日志可以看出,启动默认模式Activity,会在启动它的任务栈中创建新的实例。
结论
在此模式下,每次启动Activity都会在启动它的任务栈中创建新的实例。
singleTop(栈顶单例模式)
举个栗子
- 正常情况
首先将Activity1的启动模式设置为singleTop
,Activity1 启动 Activity2,Activity2 再启动 Activity1。下面是输出的日志:
com.demo.activity.Activity1@61b47ba
com.demo.activity.Activity2@d404aa5
com.demo.activity.Activity1@c371793
Activity2 启动 Activity1 的时候,Activity2位于栈顶,Activity1位于栈底,依然创建了新的 Activity1 实例。
- 启动自身
我们将 Activity2 设置为singleTop
,并且在Activity2中启动它本身。下面是输出的日志:
com.demo.activity.Activity1@6bbba71
com.demo.activity.Activity2@34fb18c
Activity2 onNewIntent()
Activity2 启动它本身,并没有再创建新的实例,但是调用了它的onNewIntent方法。
- 跨程序启动
先启动App1,再启动App2,App2启动App1中的Activity2:
D/ActivityOne: com.demo.activity.Activity1@2946b4d onCreate taskId: 64
D/ActivityTwo: com.demo.activity.Activity1@2946b4d onCreate taskId: 65
D/ActivityOne: com.demo.activity.Activity2@1a7626a onCreate taskId: 65
再来看看App1中已经存在singleTop
模式的Activity2实例情况下,App2调用会发生什么情况:
D/ActivityOne: com.demo.activity.Activity1@2946b4d onCreate taskId: 67
D/ActivityOne: com.demo.activity.Activity2@dcb37f8 onCreate taskId: 67
D/ActivityTwo: com.demo.activity.Activity1@2946b4d onCreate taskId: 68
D/ActivityOne: com.demo.activity.Activity2@ae41b40 onCreate taskId: 68
根据输出日志可知,和standard
模式情况一样,都会在启动它的任务栈中创建新的实例(只要启动它的任务栈栈顶不是它,都会创建新的)。
结论
当将要启动的Activity已经位于栈顶时(已经存在,并且位于栈顶),将不会再创建实例,会调用该Activity实例的onNewIntent函数。如果Activity不在栈顶,则会和standard模式一样,创建新的实例,并放入启动它的任务栈栈顶。
singleTask (栈内单例模式)
举个栗子
- 同一App内
创建3个Activity,并将Activity2设置为singleTask
。Activity1 -> Activity2 -> Activity3 -> Activity2,下面是输出日志:
D/Activity1: com.demo.activity.Activity1@342e665c taskId: 21
D/Activity1: onStart
D/Activity1: onResume
D/Activity1: onPause
D/Activity2: com.demo.activity.Activity2@2540cea8 taskId: 21
D/Activity2: onStart
D/Activity2: onResume
D/Activity1: onActivitySaveInstanceState
D/Activity1: onStop
D/Activity2: onPause
D/Activity3: com.demo.activity.Activity3@38fddd69 taskId: 21
D/Activity3: onStart
D/Activity3: onResume
D/Activity2: onActivitySaveInstanceState
D/Activity2: onStop
D/Activity3: onPause
D/Activity2: Activity2 onNewIntent()
D/Activity2: onStart
D/Activity2: onResume
D/Activity3: onStop
D/Activity3: onDestroy
当Activity3启动Activity2之后,Activity3进入了销毁生命周期,而Activity2分别调用了 onNewIntent
-> onStart
-> onResume
,并没有创建新的Activity2实例。
- 跨App调用
App2启动并调用App1的Activity2(singleTask):
D/ActivityTwo: com.demo.activity.Activity1@2946b4d onCreate taskId: 70
D/ActivityOne: com.demo.activity.Activity2@2946b4d onCreate taskId: 71
taskId不同,创建了新的栈,并在其栈底实例化新实例。
App2和App1都启动的情况,App2调用:
D/ActivityTwo: com.demo.activity.Activity1@2946b4d onCreate taskId: 72
D/ActivityOne: com.demo.activity.Activity2@2946b4d onCreate taskId: 73
D/ActivityOne: com.demo.activity.Activity2@1a7626a onCreate taskId: 73
在上面基础上,再使用App2调用:
D/ActivityOne: com.demo.activity.Activity2@1a7626a onNewIntent() taskId:73
App1的Activity2并没有重新创建新实例。
结论
和singleTop类似,只不过singleTop是检测栈顶元素是否是需要启动的Activity,而singleTask是检测整个栈中是否存在当前需要启动的Activity。如果存在,则将该Activity以上的Activity退栈销毁,让该Activity置顶,也会触发onNewIntent。
以上指的是同一APP中启动singleTask的Activity,如果是其他程序以singleTask模式来启动该Activity,会创建一个新的任务栈。如果启动模式为singleTask的Activity已经在后台一个任务栈中存在,那么启动后,后台的这个任务栈将一起被切换到前台。
值得注意的是:
singleTask
模式启动的Activity所存在的任务栈,可以由<activity>
的参数taskAffinity
来设置。点击查看(处理关联)
singleInstance(全局单例模式)
举个栗子
- 将Activity2设置为
singleInstance
,启动Activity1,Activity1再启动Activity2:
D/ActivityOne: com.demo.activity.Activity1@2946b4d onCreate taskId: 83
D/ActivityOne: com.demo.activity.Activity2@177dba4 onCreate taskId: 84
- 使用App2调用已经启动的上述Activity2:
D/ActivityTwo: com.demo.activity.Activity1@2946b4d onCreate taskId: 88
D/ActivityOne: com.demo.activity.Activity2@177dba4 onNewIntent() taskId: 84
结论
该模式的Activity会在一个独立的任务栈中开启,并且这个任务栈中有且仅有这一个实例。当再次启动该Activity时,会重用已存在的任务栈和实例,并且会调用该实例的onNewIntent函数。同一时刻在系统中只会存在一个这样的Activity实例。
Intent Flags
除了在清单文件中配置launchMode
来设置启动模式外,还可以在使用startActivity
时给Intent
设置相应的Flag,来达到相应的效果。
FLAG_ACTIVITY_NEW_TASK
使用一个新的Task来启动Activity,如果已有正在启动Activity的运行任务,则该任务会转到前台并恢复其最后状态,同时Activity会在onNewIntent()中收到新Intent。与”singleTask”launchMode是一样的。
FLAG_ACTIVITY_SINGLE_TOP
和singleTop效果相同。
FLAG_ACTIVITY_CLEAR_TOP
如果正在启动的 Activity 已在当前任务中运行,则会销毁当前任务顶部的所有 Activity,并调用onNewIntent传递Intent,不会创建新实例。
FLAG_ACTIVITY_CLEAR_TOP
通常与FLAG_ACTIVITY_NEW_TASK
结合使用。一起使用时,通过这些标志,可以找到其他任务中的现有 Activity,并将其放入可从中响应 Intent的位置。
注:如果指定 Activity 的启动模式为”standard”,则该 Activity 也会从堆栈中移除,并在其位置启动一个新实例,以便处理传入的 Intent。这是因为当启动模式为”standard”时,将始终为新 Intent 创建新实例。
FLAG_ACTIVITY_NO_HISTORY
当该模式启动的ActivityA再启动ActivityB后,ActivityA就消失了,不会保留在Activity栈中。
参考文案
《Android开发艺术探索》—— 任玉刚著
官方文档
浅析Activity启动模式相关推荐
- activity 启动模式_腾讯大牛:你根本不懂Activity!
码个蛋(codeegg)第 583 次推文 作者:厘米姑娘 原文:https://www.jianshu.com/p/602b1ec4ca7a 在之前的Activity篇主要学习Activity的生命 ...
- Android初级开发笔记-- activity启动模式的学习(1)
第一次学习Android中一个很重要的概念,启动模式.文章记录的也只是一些入门知识,随着学习的深入还会有activity启动模式的学习(2)和(3). 下面分三个小点说一下对启动模式的理解区别以及如何 ...
- activity 启动模式_Android世界:Activity的启动模式及其适用范围
一.Activity启动模式简介 activity启动模式,可以理解为activity在任务栈(也叫"回退栈")的回退规则,即点击"back"键时,activi ...
- Android开发面试题之Activity启动模式讲解总结
activity启动模式分为: Standard :默认的启动模式每次启动activity都会新建一个activity,不管是否此activity是否存在 SingleTop :栈顶复用模式,每次启动 ...
- Android activity启动模式
如何正确理解和使用 Activity的4种启动模式 关于Activity启动模式的文章已经很多,但有的文章写得过于简单,有的则过于注重细节,本文想取一个折中,只关注最重要和最常用的概念,原理和使用方法 ...
- Android中Activity启动模式详解
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...
- Android中Activity启动模式
Android中Activity启动模式一共是四种,这里我写一下我对其的理解: 1.standard(默认) 2.singleTop,如果某个Activity设置了该属性,且当前Activity就是这 ...
- Android系统(187)---最易懂的Activity启动模式详解
Android基础:最易懂的Activity启动模式详解 前言 Android基础中,Activity的启动模式非常重要 本文将全面介绍 Activity的启动模式 目录 目录 1. 定义 即Acti ...
- activity启动模式你所不知道的异常情况
前言 虽然了解activity的四种启动模式,但是在一些复杂场景下,各种启动模式会出现的现象,以及现象的原因并不清楚,再加上个taskAffinity launchMode clearTaskOnLa ...
最新文章
- 教程:13、用户管理
- Filtration, σ-algebras
- Android开发笔记(四十八)Thread类实现多线程
- CSS案例2:用定位是实现三级导航
- 企业微信第三方服务商应用开发及上架教程
- php通用补丁,PHP受权验证系统V2.1完整版 带补丁包
- python 微信分享链接_python如何爬取搜狗微信公众号文章永久链接的思路解析
- 天图投资境外上市获批:上半年营收降​18% 投了小红书与百果园
- js监听鼠标拖动事件(按住左键拖动触发,松开左键取消)
- 每日算法----929. 独特的电子邮件地址----2022/06/04
- 京瓷1025打印机打印有底灰简单处理
- idea永久激活使用
- storm滑动时间窗口实现
- 根据在同一时间使用计算机用户的多少,2016年职称计算机WindowsXP考前冲刺试题1...
- java静态方法高级用法_Spock高级用法 – 动态mock
- 上网行为管理系统可以应用在哪些行业
- python编程软件手机版下载_Python编程狮
- 深入理解LInux ELF可执行程序
- The Lighting Handbook, Tenth Edition 读书札记
- autojs文档(包括4.1.0、9、autoxjs)
热门文章
- fsk调制matlab 仿真,基于MATLAB对FSK信号调制与解调的仿真
- YV12和YUY2的基本知识
- TypeScript+Vue
- 达梦数据库使用--建表
- 简单解析一下扫码登陆原理,简单到你想不到!
- 【机器学习|数学基础】Mathematics for Machine Learning系列之线性代数(3):行列式的性质
- CAD如何绘制A0/A1/A2/A3/A4图框?
- php怎么加css和背景图,如何使用css中:after伪元素实现背景图片的叠加层?
- 技术er的公众号运营方法论
- 基于Fabric+IPFS大规模数据上链方案