Android开发艺术2之Activity的启动模式
Activity是Android的四大组件之一,他的重要性毋庸置疑,对于这么重要的一个组件,我们首先要知道这些都是由系统进行管理和回调的,要理解Activity的启动模式,我们首先来了解一下Android中的任务栈。
任务栈Task,是一种用来放置Activity实例的容器,他是以栈的形式进行盛放,也就是所谓的先进后出,2个基本操作:压栈和弹出,所以在其中只能根据压栈和弹出操作更改Activity的顺序。我们启动一个Application的时候,系统会为它默认创建一个对于的Task,用来盛放根Activity,默认启动Activity会放在同一个Task中,新启动的Activity会被压入启动它的那个Activity的栈中,并且显示他,当用户按下回退键时,这个Activity就会被弹出栈,按下Home键回到桌面,再启动另一个应用,这时候之前那个Task就被移到后台,成为后台任务栈,而刚启动的那个Task就被调到前台,成为前台任务栈,Android系统显示的就是前台任务栈中的Top实例Activity,当然,同一个应用可以有多个任务栈,但是肯定只存在一个任务栈在前台。对于任务栈的调配应该大概了解了,下面提一下他的一个重要的属性taskaffinity,也就是所谓的亲和力。这个属性不光Task有,Activity也有(affinity),他们就是通过这个属性值来进行关联的,不然你想想,一个应用有这么多Activity,并且可以有多个task,那么让activity实例随便入哪个栈都行,那岂不是乱成一团了。
affinity系统默认会给他一个值,那就是应用的包名。并且如果自己重新给他值的话就在xml文件中定义,但是他的定义必须包含".",也就是像包名一样中间要有点号。
以上简单的介绍了任务栈,下面我们正式讲下我们的Activity的启动模式和标志位,首先分为四种启动模式,分别为:标准模式,栈顶复用模式,栈内复用模式,单例模式。
1.standard即标准模式,他是系统默认的启动方式,这个任务栈中可以有多个相同的Activity实例,多个相同Activity实例也可以分布在不同的任务栈中,这时候是谁启动他,他就和谁在一个任务栈中,这时候我们要联系到我们遇到过的一个异常:android.util.AndroidRuntimeException:....,具体内容大家试试这样启动一个Activity就会出来,使用ApplicationContext启动一个standard模式的Activity。我们分析下,其实这个错误的出现就是因为默认模式下,被谁启动,activity就翻到那个任务栈中去,而全局的上下文对象是没有任务栈存在的,所以就会报错了,解决这个问题可以更改启动的上下文为某个activity对象,当然我们如果将被启动的activity设置他的标志位为FLAG_ACTIVITY_NEW_TASK 也同样可以,这时候就相当于把Activity改为了singleTask模式启动了。
2.singleTop即栈顶唯一模式,这种模式下,如果Activity位于任务栈的栈顶,那么此Activity不会被重新创建,也就是说不会调用生命周期中的onCreate和onStart方法,但是会回调另一个方法onNewIntent,这时候我们可以在这个回调方法里根据参数Intent intent进行自己的相关处理。如果新启动的Activity实例不存在,或者存在但是不是位于栈顶,那么和正常一样的创建它。
3.singleTask即栈内唯一,这个其实是一种单例模式,只要这个任务栈中存在这个Activity的实例,那么就不再创建它,而是直接复用其实例,这时候也会回调onNewIntent,这时候有个问题,这个实例如果不是在栈顶,那么它要到栈顶来,唯一途径就是把它之前的实例全部弹出,实际上就是说singleTask具有clearTop的效果。当然这是简单的说明,下面几个例子让你更能理解:
例1.目前有S1任务栈中有ABC,这个时候要启动Activity D并且D是singleTask模式,其所需的任务栈为S2(之所以不是S1因为为他指定了affinity属性),这时候由于S2和D都不存在,所以会先创建任务栈S2,然后在创建实例D压入栈底。
例2.情况和1相同,只是D所需任务栈同样是S1,这时候就只要创建D的实例并将其压入到栈S1中即可。
例3.如果D所需的任务栈为S1,并且当前S1中的情况为ADBC,这时候D的实例存在了,那么会将BC出栈,剩下AD,这就是singleTask默认具有clearTop的效果
4.singleInstance 单例模式,这是一种加强型的singleTask,他具有singleTask的所有特性,并且拥有一个独特的地方就是,他会单独占用一个任务栈,比如Activity A是singleInstance模式,那么启动他的时候,系统会为他单独创建一个任务栈将其压入,如果再次启动他,他已经存在了,那么就直接复用该任务栈。
以上就是关于启动模式的说明,注意一点就是TaskAffinity这个属性主要是与singleTask或者allowTaskReparenting属性配对使用,在其他情况下是没有意义的。
下面讲下关于标志位,Activity的标志位Flags有很多种,其效果也有很多,比如可以用来设定启动模式,可以用来影响运行状态,下面介绍几个常用的标志位:
FLAG_ACTIVITY_NEW_TASK
该标志位作用于指定Activity的singleTask启动模式一样。
FLAGE_ACTIVITY_SINGLE_TOP
该标志位的作用和指定Activity的singleTop效果一致。
FLAGE_ACTIVITY_CLEAR_TOP
此标记位的效果就有意思了,拥有它的Activity会将与他在同一个任务栈中之前Activity都出栈,这个标志通常和singleTask配合使用时,如果实例存在,就调用他的onNewIntent,并将他之上的其他实例都清除,但是如果拥有该标志位的Activity是默认启动模式standard,那么他会连同自己一起清除,然后再重新创建实例,这点要注意好,所以之前我们说了singleTask默认具有此标志的效果
以上就是简单的说了一下启动模式和标志位。为Activity设置启动模式我们有2中方式:
1.在XML文件中定义 android:launchMode="singleTask"
2.在启动意图的时候设置:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
这俩种方式存在一些区别:
优先级第二种大于第一种,当俩种方式同时存在的时候以第二种方式为准,第一种方式为辅。俩种方式也存在适用范围的区别,第一种方式无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标志的效果,而第二种方式无法直接设置出singleInstance模式的效果。
希望看完能让你在开发中对启动模式和flags标志位进行灵活使用~~~
Android开发艺术2之Activity的启动模式的更多相关文章
- Android开发艺术1之Activity的生命周期
作为<Android开发艺术探索>这本书的第一篇博客,我就多说几句.本系列博客旨在对书中相关内容进行解读,简化,提供一个入门到提高的流程.不敢说书评,也不能说教程,只希望对有些人有帮助就好 ...
- Android笔记(五) Activity的启动模式
Android中Activity是由返回栈来管理的,在默认情况下,每当启动一个新的Activity,它都会在返回栈中入栈,并且出于栈的顶端.但是有些时候Activity已经在栈的顶端了,也就不需要再启 ...
- Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式
Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...
- Android开发艺术探索(一)——Activity的生命周期和启动模式
Activity的生命周期和启动模式 生命周期有? 1.典型情况下的生命周期—>指有用户参与的情况下,Activity所经过的生命周期改变 2.异常情况下的生命周期—>指Activity被 ...
- 《Android开发艺术探索》读书笔记 (1) 第1章 Activity的生命周期和启动模式
第1章 Activity的生命周期和启动模式 1.1 Activity生命周期全面分析 1.1.1 典型情况下生命周期分析(1)一般情况下,当当前Activity从不可见重新变为可见状态时,onRes ...
- Android开发艺术探索笔记之Activity
内容来源:Android开发艺术探索第一章:Activity的生命周期与启动模式 不能在onPause中做重量级的操作,因为必须执行完成以后新Activity才能Resume.onPause和onSt ...
- Android开发艺术探索读书笔记——01 Activity的生命周期
http://www.cnblogs.com/csonezp/p/5121142.html 新买了一本书,<Android开发艺术探索>.这本书算是一本进阶书籍,适合有一定安卓开发基础,做 ...
- Android开发9——Activity的启动模式
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. 一. ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
随机推荐
- Angular.js之服务与自定义服务学习笔记
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- MySQL · 引擎特性 · InnoDB IO子系统
前言 InnoDB做为一款成熟的跨平台数据库引擎,其实现了一套高效易用的IO接口,包括同步异步IO,IO合并等.本文简单介绍一下其内部实现,主要的代码集中在os0file.cc这个文件中.本文的分析默 ...
- C++ 11和C++98相比有哪些新特性
此文是如下博文的翻译: https://herbsutter.com/elements-of-modern-c-style/ C++11标准提供了许多有用的新特性.这篇文章特别针对使C++11和C++ ...
- 【2017-03-05】函数基础、函数四种结构、ref和out参数、递归
一.函数基础 1.函数/方法:非常抽象独立完成某项功能的一个个体 2.函数的作用: 提高代码的重用性提高功能开发的效率提高程序代码的可维护性 3.分类 固定功能函数高度抽象函数 4.函数四要素:输入, ...
- Think PHP 基础
ThinkPHP 一.什么框架: 一堆代码的集合,里边有变量.函数.类.常量,里边也有许多设计模式MVC.AR数据库.单例等等. 框架可以节省我们50-60%的工作量,我们全部精力都集中在业务层次. ...
- how to use Prolog in C#? SWI-Prolog
上个月突然看到Prolog这门语言,它特殊的语法吸引了我,但是经过我一段时间的学习,发现它也不像网络上传说的那样神奇,不过我依然对它很感兴趣,有前辈说Prolog本身并不强大,但是用来作为一门辅助语言 ...
- JAVA基础知识系列---进程、线程安全
1 相关概念 1.1 临界区 保证在某一时刻只有一个线程能访问数据的简便方法,在任意时刻只允许一个线程对资源进行访问.如果有多个线程试图同时访问临界区,那么在有一个线程进入后,其他所有试图访问临界区的 ...
- Python3处理配置文件
1.说明:python3使用configparser模块来处理ini配置文件.2.代码示例:需要生成conf.ini配置文件如下:[config]v1 = 100v2 = abcv3 = truev4 ...
- Eclipse 项目导入 Studio Debug运行卡死在进入界面
最近,把一个以前开发的Eclipse的项目导入Studio中,遇到了各种奇葩的问题,这时候就要参考百度了,基本都能解决,我导入的项目遇到的问题在百度中都能找到答案,那么我这里就不在做总结了 第二天,发 ...
- Java集合ArrayList源码解读
最近在回顾数据结构,想到JDK这样好的代码资源不利用有点可惜,这是第一篇,花了心思.篇幅有点长,希望想看的朋友认真看下去,提出宝贵的意见. :) 内部原理 ArrayList 的3个字段 priva ...