startActivity()的流程

来源:互联网 发布:成都数据恢复公司 编辑:程序博客网 时间:2024/05/19 11:44

10.1.3  startActivity()的流程(1)

程序员可以直接调用startActivity()启动指定的Activity。前面说过,尽管从用户的角度来看,启动Activity有不同的方式,但是其主体流程是完全相同的,前端各种交互方式最后都会调用到startActivity()启动。因此,首先介绍startActivity()的流程。

1.概述

调用流程可大致归结为如图10-1和图10-2所示,由于版面限制,该图被划分为两部分。

 图10-1  startActivity()的内部调用流程

一般调用startActivity()方法是从用户单击桌面图标开始的,经过各种调用,最后导致调用startActivity()。本例假设当前正在运行A,而单击图标后会运行B。

AmS收到客户请求startActivity()后,会首先暂停当前的Activity,因此要判断mResumedActivity是否为空。在一般情况下,该值都不为空,如果不为空,AmS会通知A所在客户进程暂停,执行该Activty,并立即返回,返回后AmS就又"睡觉"去了。读者可能觉得奇怪,AmS"睡觉"去了,谁来启动B呢?这正是AmS的异步机制的好处,异步机制允许执行完一个命令后就去休息,而当远程执行完某个命令后再回调。这种方式广泛应用于Android的内核实际中,大家要迅速解除这种疑惑。

当A进程完成暂停后,报告AmS,这时AmS开始执行completePaused()。该方法中先要检查目标Activity是否在mHistory列表中,如果在,说明目标进程还在运行,目标Activity只是处于stop状态,还没有finish,所以通知B进程直接resume指定的Activity即可。如果不在mHistory列表中,则继续执行如图10-2所示的流程。

 图10-2  startActivity()的内部调用流程(续)

检查目标Activity所在的进程是否存在,如果不存在则必须首先启动对应的进程。当对应的进程启动后,B进程会报告AmS自己已经启动,于是执行AmS的attachApplication()方法,该方法可理解为B进程请求AmS给自己安排(attach)一个具体要执行的Activity,此时AmS继续调用resumeTopActivity(),通知B进程执行指定的Activity。如果指定的HistoryRecord在B进程中不存在,则B调用handleLaunchActivity()创建一个该Activity实例;如果已经存在,则调用handleResumeActivity()恢复已有的Activity的运行。这个逻辑的意思就是说,在ActivityThread中可以存在同一个Activity的多个实例,对应了AmS中mHistory的多个HistoryRecord对象。在一般情况下,当调用startActivity(intent)的FLAG为NEW_TASK时,AmS会首先从mHistory中找到指定Activity所在的Task,然后启动Task中的最后面一个Activity;如果FLAG不为NEW_TASK,那么AmS会在当前Task中重新创建一个HistoryRecord,这就有可能创建同一个Activity的多个HistoryRecord对象,在ActivityThread端就可能创建同一个Activity类的多个实例。

2.单击图标的过程

关于startActivity()的细节过程如附图3所示,本图绘制时遵循以下规则:

假设class A的内部函数关系如下示意代码。

  1. public class Persedu {  
  2.     void f1(){  
  3.         f2();  
  4.     }  
  5.       
  6.     void f2(){  
  7.         f3();  
  8.     }  
  9.       
  10.     void f3(){  
  11.         x1();  
  12.         x2();  
  13.         x3();  
  14.     }  
  15.       
  16.     void x1(){};  
  17.     void x2(){};  
  18.     void x3(){};  
  19. }  
0 0
原创粉丝点击