Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1521757
  • 博文数量: 465
  • 博客积分: 8915
  • 博客等级: 中将
  • 技术积分: 6365
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-30 15:05
文章分类

全部博文(465)

文章存档

2017年(33)

2016年(2)

2015年(4)

2014年(29)

2013年(71)

2012年(148)

2011年(178)

分类: 嵌入式

2011-09-29 17:12:23

Activity调度机制

10.1  Activity调度机制

Android中,Activity调度的基本思路是这样的:各应用进程要启动新的Activity或者停止当前的Activity,都要首先报告给AmS,而不能“擅自处理”。AmS在内部为所有应用进程都做了记录,当AmS接到启动或停止的报告时,首先更新内部记录,然后再通知相应客户进程运行或者停止指定的Activity。由于AmS内部有所有Activity的记录,也就理所当然地能够调度这些Activity,并根据Activity和系统内存的状态自动杀死后台的Activity

具体来讲,启动一个Activity有以下几种方式。

在应用程序中调用startActivity()启动指定的Activity

Home程序中单击一个应用图标,启动新的Activity

按“Back”键,结束当前Activity,自动启动上一个Activity

长按“Home”键,显示出当前任务列表,从中选择一个启动。

这四种启动方式的主体处理流程都会按照第一种启动方式运行,后面三种方式只是在前端消息处理上各有不同,因此,后面首先介绍第一种启动方式,然后介绍其他启动方式的前端处理差异。

10.1.1  几个重要概念

AmS中定义了几个重要的数据类,分别用来保存进程(Process)、活动(Activity)和任务(Task)。

1.进程数据类ProcessRecord

该类在framework/base/services/java/com/android/server/am/路径下,该路径最后的am代表Activity Manager,和AmS有关的重要类都在该目录下。

一个APK文件运行时会对应一个进程,当然,多个APK文件也可以运行在同一个进程中。ProcessRecord正是记录一个进程中的相关信息,该类中内部变量可分为三个部分,大家先不用琢磨具体某个变量如何被使用,而只需要先了解它们的作用。这三个部分如表10-1所示。

 

2HistoryRecord数据类

AmS中使用HistoryRecord数据类来保存每个Activity的信息,有些读者可能奇怪,Activity本身也是一个类啊,为什么还要用HistoryRecord来保存Activity的信息,而不直接使用Activity呢?因为,Activity是具体的功能类,这就好比每一个读者都是一个Activity,而“学校”要为每一个读者建立一个档案,这些档案中并不包含每个读者具体的学习能力,而只是学生的籍贯信息、姓名、出生年月、家庭关系等。HistoryRecord正是AmS为每一个Activity建立的档案,该数据类中的变量主要包含两部分,如表10-2所示。

 

 

需要注意,HistoryRecord类也是一个Binder,它基于IApplicationToken.Stub类,因此,可以被IPC调用,一般是在WmS中进行该对象的IPC调用。

3TaskRecord

AmS中使用任务的概念确保Activity启动和退出的顺序。比如以下启动流程,ABC分别代表三个应用程序,数字123分别代表该应用中的Activity

A1A2A3B1B2C1C2,此时应该处于C2,如果AmS中没有任务的概念,此时又要从C2启动B1,那么会存在以下两个问题:

虽然程序上是要启动B1,但是用户可能期望启动B2,因为B1B2是两个关联的Activity,并且B2已经运行于B1之后。如何提供给程序员一种选择,虽然指定启动B1,但如果B2已经运行,那么就启动B2

假设已经成功从C2跳转到B2,此时如果用户按“Back”键,是应该回到B1呢,还是应该回到C2

任务概念的引入正是为了解决以上两个问题,HistoryRecord中包含一个int task变量,保存该Activity所属哪个任务,程序员可以使用Intent.FLAG_NEW_TASK标识告诉AmS为启动的Activity重新创建一个Task

有了Task的概念后,以上情况将会是这样的:

虽然程序明确指定从C2启动到B1,程序员可以在intentFLAG中添加NEW_TASK标识,从而使得AmS会判断B1是否已经在mHistory中。如果在,则找到B1所在的Task,并从该Task中的最上面的Activity处运行,此处也就是B2。当然,如果程序的确要启动B1,那么就不要使用NEW_TASk标识,使用的话,mHistory中会有两个B1记录,隶属于不同的Task

TaskRecord类中的变量如表10-3所示。

 

 

需要注意的是,TaskRecord中并没有该任务中所包含的Activity列表,比如ArrayList或者HistoryRecord[]之类的变量,这意味着不能直接通过任务id找到其所包含的Activity。要达到这个目的,可以遍历AmSmHistory中的全部HistroyRecord,然后根据每一个HistoryRecord中的TaskRecord task变量确定是否属于指定的任务。

 

本文选自《Android内核剖析 》一书

图书详细信息:http://blog.chinaunix.net/space.php?uid=13164110&do=blog&id=2897431

阅读(1034) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~