1.LocalActivityManager的说明

LocalActivityManager是Android封装的把activity转换成view对象的一个api.

2.LocalActivityManager用法

LocalActivityManager类是管理activity的,然后通过startActivity(String id,Intent intent)这个方法获取Window获取当前Window对象,再然后调用getDecorView()方法获取当前activity对应的view,然而在添加view对象的时候会遇到这个问 题:Caused by: java.lang.IllegalStateException: Activities can't be added until the containing group has been created.
解决办法:LocalActivityManager mLocalActivityManager;oncreate()方法实例化mLocalActivityManager = new LocalActivityManager((Activity) context, true);在oncreate,onresume,onpause方法中分别加入如下代码:oncreate()--------------mLocalActivityManager.dispatchCreate(arg0);参数arg0为oncreate方法的形参onpause()--------------mLocalActivityManager.dispatchPause(isFinishing());传入trueonresume()--------------mLocalActivityManager.dispatchResume();

LocalActivityManager的内部机制详解

LocalActivityManager的内部机制

LocalActivityManager内部机制的核心在于,它使用了主线程对象mActivityThread来装载指定的Activity。注意,这里是装载,而不是启动,这点很重要。

所谓的启动,一般是指会创建一个进程(如果所在应用进程还不存在)运行该Activity,而装载仅仅是指把该Activity作为一个普通类进行加载,并创建一个该类的对象而已,而该类的任何函数都没有被运行。

LocalActivityManager提供了一个重要方法startActivity(),该方法正是利用主线程mActivityThread去装载指定的Activity,其执行过程如图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对象的视图内容有一个正确的呈现。

ActivityGroup内部的Activity生命期控制

前面分析了LocalActivityManager内部的执行原理,接下来分析一个有意思的问题:”在TabActivity的多个Tab页切换时,内嵌的Activity对象会在onPause()和onResume()之间切换吗?”

从上面的分析可知,Manager装载Activity的目的仅仅是为了获取其所包含的Window对象,而一旦获取后,则似乎不需要再纠缠于 Activity本身的生命期状态变换操作。其实笔者也是这么认为的,可以尝试屏蔽以下代码,该段代码的作用是在装载下一个Activity之前先暂停当 前的Activity对象。

屏蔽后,运行结果丝毫不受影响,原因很简单,这里做暂停的目的仅仅为了保持Activity原有的生命期过程,从而可以保持原有Activity释 放相关资源的行为。比如当Activity A以启动的方式运行时,如果另一个Activity B要启动,则会先暂停A。在一般的程序设计中,暂停会回调onPause()操作,如果该Activity使用了大量的内存或者其他资源,在 onPause()函数中程序员可能会尝试释放这些资源以提高系统效率,这就是为什么在LocalActivityManager中也保持了这种流程的原 因。当然,如果你不释放,也不会发生什么逻辑错误。

而在以上代码的moveToState()操作中调用了mActivityThread的onPause()或者onStop()操作,这就是为什 么在Tab页切换时,对应的Activity也会执行onPause()或者onStop()的原因。这完全与AmS无关,因此不要因为这个而产生 TabActivity同时运行了两个Activity(TabActivity本身和嵌入的Activity)的错觉。

另外还有一个有意思的问题,请思考下面的操作过程。

打开一个TabActivity,比如”联系人”程序,在上面的四个Tab页上都点一次,然后再按”Home”键回到桌面,然后再从联系人图标中进入该程序。请思考此时TabActivity内嵌的Activity会发生生命期状态改变吗?

首先TabActivity当然会从stop状态转变为start状态,并先后调用onStart()和onPause()。因为它是一个标准的 Activity,TabActivity的父类是ActivityGroup,而在该类中,相应的onXXX()方法内部都增加了 mLocalActivityManager.dispatchXXX()代码,比如:

 protected void onResume() {mLocalActivityManager.dispatchResume();};

而在LocalActivityManager中,dispatchXXX()则会把相应的 action再dispatch到所包含的所有嵌入式Activity对象中。所以,以上问题的答案是内嵌的Activity生命期会从stop状态转换 到resume状态。仔细查看ActivityGroup的onXXX()函数发现,唯独没有onStart()方法,其原因是在 LocalActivityManager的moveToState()方法中可以直接把子Activity的状态从stop改变到resume,所以, 此处可以省略对onStart()的重载。
1.LocalActivityManager的说明

LocalActivityManager是Android封装的把activity转换成view对象的一个api.

2.LocalActivityManager用法

LocalActivityManager类是管理activity的,然后通过startActivity(String id,Intent intent)这个方法获取Window获取当前Window对象,再然后调用getDecorView()方法获取当前activity对应的view,然而在添加view对象的时候会遇到这个问 题:Caused by: java.lang.IllegalStateException: Activities can't be added until the containing group has been created.
解决办法:LocalActivityManager mLocalActivityManager;oncreate()方法实例化mLocalActivityManager = new LocalActivityManager((Activity) context, true);在oncreate,onresume,onpause方法中分别加入如下代码:oncreate()--------------mLocalActivityManager.dispatchCreate(arg0);参数arg0为oncreate方法的形参onpause()--------------mLocalActivityManager.dispatchPause(isFinishing());传入trueonresume()--------------mLocalActivityManager.dispatchResume();

LocalActivityManager的内部机制详解

LocalActivityManager的内部机制

LocalActivityManager内部机制的核心在于,它使用了主线程对象mActivityThread来装载指定的Activity。注意,这里是装载,而不是启动,这点很重要。

所谓的启动,一般是指会创建一个进程(如果所在应用进程还不存在)运行该Activity,而装载仅仅是指把该Activity作为一个普通类进行加载,并创建一个该类的对象而已,而该类的任何函数都没有被运行。

LocalActivityManager提供了一个重要方法startActivity(),该方法正是利用主线程mActivityThread去装载指定的Activity,其执行过程如图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对象的视图内容有一个正确的呈现。

ActivityGroup内部的Activity生命期控制

前面分析了LocalActivityManager内部的执行原理,接下来分析一个有意思的问题:”在TabActivity的多个Tab页切换时,内嵌的Activity对象会在onPause()和onResume()之间切换吗?”

从上面的分析可知,Manager装载Activity的目的仅仅是为了获取其所包含的Window对象,而一旦获取后,则似乎不需要再纠缠于 Activity本身的生命期状态变换操作。其实笔者也是这么认为的,可以尝试屏蔽以下代码,该段代码的作用是在装载下一个Activity之前先暂停当 前的Activity对象。

屏蔽后,运行结果丝毫不受影响,原因很简单,这里做暂停的目的仅仅为了保持Activity原有的生命期过程,从而可以保持原有Activity释 放相关资源的行为。比如当Activity A以启动的方式运行时,如果另一个Activity B要启动,则会先暂停A。在一般的程序设计中,暂停会回调onPause()操作,如果该Activity使用了大量的内存或者其他资源,在 onPause()函数中程序员可能会尝试释放这些资源以提高系统效率,这就是为什么在LocalActivityManager中也保持了这种流程的原 因。当然,如果你不释放,也不会发生什么逻辑错误。

而在以上代码的moveToState()操作中调用了mActivityThread的onPause()或者onStop()操作,这就是为什 么在Tab页切换时,对应的Activity也会执行onPause()或者onStop()的原因。这完全与AmS无关,因此不要因为这个而产生 TabActivity同时运行了两个Activity(TabActivity本身和嵌入的Activity)的错觉。

另外还有一个有意思的问题,请思考下面的操作过程。

打开一个TabActivity,比如”联系人”程序,在上面的四个Tab页上都点一次,然后再按”Home”键回到桌面,然后再从联系人图标中进入该程序。请思考此时TabActivity内嵌的Activity会发生生命期状态改变吗?

首先TabActivity当然会从stop状态转变为start状态,并先后调用onStart()和onPause()。因为它是一个标准的 Activity,TabActivity的父类是ActivityGroup,而在该类中,相应的onXXX()方法内部都增加了 mLocalActivityManager.dispatchXXX()代码,比如:

 protected void onResume() {mLocalActivityManager.dispatchResume();};

而在LocalActivityManager中,dispatchXXX()则会把相应的 action再dispatch到所包含的所有嵌入式Activity对象中。所以,以上问题的答案是内嵌的Activity生命期会从stop状态转换 到resume状态。仔细查看ActivityGroup的onXXX()函数发现,唯独没有onStart()方法,其原因是在 LocalActivityManager的moveToState()方法中可以直接把子Activity的状态从stop改变到resume,所以, 此处可以省略对onStart()的重载。

LocalActivityManager相关推荐

  1. TabActivity,LocalActivityManager,TabHost,TabWidget深度分析(二)

    本人原创,转载请注明:http://blog.csdn.net/fzh0803/archive/2011/06/21/6559239.aspx 上节分析了TabHost,这节接着分析TabWidget ...

  2. TabActivity,LocalActivityManager,TabHost,TabWidget深度分析(一)

    本人原创,转载请注明:http://blog.csdn.net/fzh0803/archive/2011/06/21/6559081.aspx TabAcitivity继承自AcitivtyGroup ...

  3. java.lang.IllegalStateException: Did you forget to call 'public void setup(LocalActivityManager acti

    在使用TabHost时有时出现Did you forget to call 'public voidsetup(LocalActivityManager activityGroup),主要是没有继承A ...

  4. LocalActivityManager详解

    1.LocalActivityManager的说明 LocalActivityManager是Android封装的把activity转换成view对象的一个api. 2.LocalActivityMa ...

  5. 一个activity显示另一个activity,LocalActivityManager实例化不是通过ActivityGroup,

    LocalActivityManager实例化不是通过ActivityGroup 通过 继承 AppCompatActivity 而不是ActivityGroup public class CeShi ...

  6. 【转】Android Activity原理以及其子类描述,androidactivity

        Android Activity原理以及其子类描述,androidactivity 简介 Activity是Android应用程序组件,实现一个用户交互窗口,我们可以实现布局填充屏幕,也可以实 ...

  7. Android Tabhost with FragmentActivity

    此文解决我这两天的问题,故转载:原文Android Tabhost with FragmentActivity   2012-05-07 更新)接續Android TabHost中切換Activity ...

  8. ActivityGroup是如何对嵌入的Activitys进行管理的

    2019独角兽企业重金招聘Python工程师标准>>> 此前,我们对Activity进行了一些学习,在Android中,还提供了一个ActivityGroup类,该类是Activit ...

  9. 高大上的Android沉浸式状态栏?

    背景 之前做过Android沉浸式状态栏的相关需求,但是一直忙于工作,没时间系统的整理下沉浸式相关的知识,所以今天抽出时间,写一篇 Android沉浸式状态栏的文章. 何为沉浸式 沉浸式就是要给用户提 ...

最新文章

  1. 云计算技术 — 云计算的未来
  2. 简(kun)单(nan)到让我开(jue)心(wang)的后缀自动机全家桶(普通后缀、广义后缀、子序列)...
  3. tcc读写文本txt文件
  4. how does tomcat access js - SAPUI5 Core Libraries
  5. 把combobox控件添加到datagridview控件中_自定义系列:控件属性添加
  6. jqgrid 横向滚动条
  7. 声卡测试音频100Hz~1KHz
  8. 计算机科学与技术民办大学排名,计算机科学与技术专业排名:这95所大学实力很强,包括公办、民办和中外合办院校...
  9. 基于人工智能的搜索引擎优化软件-市场现状及未来发展趋势
  10. 2021-12-12
  11. 【RTD】二分法查找和分段线性插值算法在RTD中应用
  12. 使用OpenCV和Python实现图像的颜色检测
  13. mysql 1146错误 修复6,MySQL中出现错误1146时出现问题
  14. The Intriguing Obsession
  15. 喏,你们要的58条 Allegro 使用技巧汇总整理好了
  16. Ionic3安装和项目创建
  17. u盘怎么安装计算机系统软件,教你怎样用u盘安装win7x64系统
  18. 技术丨如何处理有依赖的消息
  19. python自动化客户端_如何使用Python自动化登录客户端,pywinauto确实很强大
  20. 大一项目实训—学生成绩管理系统

热门文章

  1. 在填写求职简历模板时个人技能应该怎么填写?
  2. 堡垒机、跳板机JumpServer的搭建,以及使用,图文详细
  3. wait for stopper event to be increased
  4. 使用WPD API操作MTP设备一些总结
  5. RC5编码格式的遥控器解码、PCA9633器件控制代码示例、串口通信程序示例、IIC通信示例
  6. Radware:IP欺诈等让网络攻击难以防范
  7. linux 磁盘分区备份,关于GPT磁盘的分区表备份
  8. libimobiledevice的安装与使用
  9. 浙江大学计算机考研机试KY132 xxx定律
  10. 大学计算机绘图实训报告,CAD课程实习报告