Activity调度机制

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所示。

 

2.HistoryRecord数据类

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

 

 

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

3.TaskRecord类

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

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

— 虽然程序上是要启动B1,但是用户可能期望启动B2,因为B1和B2是两个关联的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,程序员可以在intent的FLAG中添加NEW_TASK标识,从而使得AmS会判断B1是否已经在mHistory中。如果在,则找到B1所在的Task,并从该Task中的最上面的Activity处运行,此处也就是B2。当然,如果程序的确要启动B1,那么就不要使用NEW_TASk标识,使用的话,mHistory中会有两个B1记录,隶属于不同的Task。

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

 

 

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

 

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

图书详细信息:http://blog.csdn.net/broadview2006/article/details/6804573

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值