LocalActivityManager的内部机制
LocalActivityManager内部机制的核心在于,它使用了主线程对象mActivityThread来装载指定的Activity。注意,这里是装载,而不是启动,这点很重要。
所谓的启动,一般是指会创建一个进程(如果所在应用进程还不存在)运行该Activity,而装载仅仅是指把该Activity作为一个普通类进行加载,并创建一个该类的对象而已,而该类的任何函数都没有被运行。
LocalActivityManager提供了一个重要方法startActivity(),该方法正是利用主线程mActivityThread去装载指定的Activity,其执行过程如图10-25所示。
|
| 图10-25 LocalActivityManager类中startActivity()的执行流程 |
Manager对象必须已经被初始化,初始化的工作是在dispatchCreate()方法中首先被完成的,而这又是在ActivityGroup类中的onCreate()中被调用的。也就是说,LocalActivityManager的startActivity()方法必须在所在的Activity的onCreate()方法执行完毕后被调用。
判断目标Activity是否包含在该Manager中。Manager中使用两个列表变量保存已经装载过的Activity对象,分别是mActivities和mActivityArray。前者是一个HashMap类型,每一个LocalActivityRecord按照一个字符串对应;后者是一个ArrayList列表。
判断装载的Activity对象是否有正处于resume状态的,如果有,则要先暂停,事实上可以完全不用暂停,暂停仅仅是Manager希望完全按照Activity对象本身的执行顺序调用它,从而使得看上去更像是一个标准的子Activity启动方式。而暂停则是通过调用moveToState()完成的。
如果目标Activity已经被装载到了当前Manager中,下面就需要判断是直接使用该Activity的当前窗口呢,还是需要先销毁该Activity,并重新调用其onCreate()?注意,这里所说的销毁仅仅是指把Activity变成"销毁"的状态而已,并不是说销毁该Activity对象。而判断的规则有点类似于AmS中根据Activity的flag执行不同的操作,其中包括是否先调用目标Activity的onNewIntent(),还包括是否是CLEAR_TOP模式。一般作为TabActivity的嵌入式Activity都不会是CLEAR_TOP模式,否则,如果多个Tab页使用同一个Activity对象将导致所显示的内容完全相同。
调用moveToState()改变指定Activity到resume状态。
返回Activity所对应的Window窗口。
从以上步骤可以看出,装载Activity对象的过程对AmS来讲是完全不可见的,因为这是装载而不是启动,因此看似TabActvity同时运行了多个Activity,而实际上仅仅是运行了ActivityGroup一个Activity。那些嵌入的Activity仅仅是贡献了自己所包含的Window窗口而已,TabActivity正是把这些Window窗口的DecorView作为tabcontent的子视图而已。
下面对moveToState(LocalActivityRecord r, int desireState)函数的过程进行说明,参数r代表目标Activity对象,desireState代表期望把目标Activity改变成哪种状态。
moveToState()函数内部首先判断r.curState是否是RESTORED或者DESTROY状态,如果是则直接返回。因为RESTORED代表刚刚创建了目标Activity对象,还没有执行onCreate()方法,所以不能改变状态;DESTROY代表已经销毁,也不能改变状态。
接着,判断r.curState是否是INITIALIZE状态,这种情况只有在第一次调用startActivity()装载目标Activity对象时才会执行到,其内部主要包括调用startActivityNow()和performResumeActivity()将目标Activity改变到STARTED或者RESUMED状态。
由于Activity当前状态不同,要想达到不同的期望状态自然需要经过不同的步骤。moveToState()函数内部正是使用switch语句先判断当前处于什么状态,然后再在case里面使用if…else语句判断期望的状态,最后再调用不同的函数。其状态和调用关系如表10-8所示,该表中调用的函数名称使用了简写,比如performRestartActivity简写为Restart。
表10-8 Activity在不同状态中转换时需执行的操作
|
目标状态 当前状态 |
CREATED |
STARTED |
RESUMED |
|
CREATED |
Restart (); |
Restart(); Resume(); |
|
|
STARTED |
Stop(); |
Resume(); |
|
|
RESUMED |
Pause(); Stop(); |
Pause(); |
从以上的步骤可以看出,startActivity()的内部执行逻辑有点像AmS中根据当前Activity状态调用不同方法。这两者就像《西游记》中的小雷音寺和大雷音寺,两者的本质区别在于LocalActivityManager仅仅是为了获取Activity对应的Window对象,中间的状态切换仅仅是为了保证Activity本身的执行过程,从而保证Window对象的视图内容有一个正确的呈现。
LocalActivityManager的内部机制的更多相关文章
- ThreadLocal内部机制及使用方法
一.介绍ThreadLocal内部机制之前,先简单说明一下其特点及用途: 1.ThreadLocal是单线程内共享资源,多线程间无法共享(即线程A访问不了线程B中ThreadLocal存放的值): 2 ...
- 搭建高可用mongodb集群(三)—— 深入副本集内部机制
在上一篇文章<搭建高可用mongodb集群(二)—— 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...
- SQL Server 内存中OLTP内部机制概述(四)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- SQL Server 内存中OLTP内部机制概述(三)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- SQL Server 内存中OLTP内部机制概述(二)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- SQL Server 内存中OLTP内部机制概述(一)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- new和instanceof的内部机制
new和instanceof的内部机制 首先我们来看看obj = new o()这条语句发生了什么: var obj = (function(){ var obj = {}; obj.__proto_ ...
- zookeeper 内部机制学习
zookeeper 内部机制学习 1. zk的设计目标 最终一致性:client不论连接到那个Server,展示给它的都是同一个视图. 可靠性:具有简单.健壮.良好的性能.如果消息m被到一台服务器接收 ...
- Python_Mix*函数名的使用以及第一类对象,闭包,迭代器,for循环的内部机制
一:函数名的应用(第一类对象) 函数名的命名规范和变量是一样的,函数名其实就是变量名, 0)函数名可以赋值给其他变量 def func(): #定义一个名为func的函数 print('my ange ...
随机推荐
- CIDR
CIDR的介绍: CIDR(Classless Inter-Domain Routing,无类域间路由选择)它消除了传统的A类.B类和C类地址以及划分子网的概念,因而可以更加有效地分配IPv4的地址空 ...
- 程序设计第三次作业--C++计算器初始部分
面向对象程序设计作业3--C++计算器初始部分 Github 链接:https://github.com/luojingzhao/object-oriented/tree/master/calcula ...
- 做fzu oj 1045 做减法学到的sprintf()函数
题目 做题一直输不出答案,于是就上网去百度了这题的解题,发现解答十分的简短,而且其中我看见了平时没见过的函数,sprintf(). 于是就百度sprintf()的使用. 如下: 函数功能:把格式化的数 ...
- C# 抽象类和接口的区别
从表象上来说,抽象类可以给出一些成员的实现,而接口却不包含成员的实现,抽象类的成员可以被继承类来部分实现,而接口类中的成员要子类来全部实现 .还有一个类可以实现多个接口,但只可以继承一个抽象类,这只是 ...
- Windows xp 重载内核(使用Irp进行文件操作)
一.前言 最近在阅读A盾代码A盾电脑防护(原名 3600safe)anti-rootkit开放源代码,有兴趣的可以去看雪论坛下载,本文代码摘自其中的重载内核. 二.实现步骤 1.ZwQuerySyst ...
- Minus-C 一个最小化的C语言规范
资深C++程序员都不会对C++编程规范太陌生,C++实在太复杂,以至于所有项目都需要裁剪一个子集共项目组内使用.经过在家休息这一小段时间,我发现其实C语言更需要一个相同的规范,这就是本文的目标,最大可 ...
- 启动tomcat时 一闪而过解决方法
1 首先确定JAVA 已经配好了环境变量,具体配置方法,找一下度娘. 测试方法:进入cmd -> javac -version 能看到JAVA的版本信息,证明配置成功了. 2 分析一下问题出现的 ...
- MySQL事务处理和锁机制
事务处理和并发性 1.1 基础知识和相关概念 1 )全部的表类型都可以使用锁,但是只有 InnoDB 和 BDB 才有内置的事务功能. 2 )使用 begin 开始事务,使用 commit 结束事务, ...
- CString和string的互相转换
CString->std::string 例子: CString strMfc=“test“; std::string strStl; strStl=strMfc.GetBuffer(0); s ...
- Hadoop集群基准测试
hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.2.0-tests.jar TestDFSIO -wri ...