zoukankan      html  css  js  c++  java
  • 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对象的视图内容有一个正确的呈现。

    Le王冬冬 博客分享地址: http://www.cnblogs.com/dongdong230/ 每个人都应做一天攻城狮
  • 相关阅读:
    微信支付(APP支付)-服务端开发(一)
    C#去除HTML标签
    监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile
    SQL总结(六)触发器
    sql中索引不会被用到的几种情况
    Sql Server参数化查询之where in和like实现详解
    Sql Server查询性能优化之不可小觑的书签查找
    浅析Sql Server参数化查询
    Sql Server查询性能优化之走出索引的误区
    IScroll在某些win10版本下的奇怪问题
  • 原文地址:https://www.cnblogs.com/dongdong230/p/4183063.html
Copyright © 2011-2022 走看看