本文原创 ,转载必须注明出处 :http://blog.csdn.net/qinjuning
今天主要分析下ActivityManagerService(服务端) 与应用程序(客户端)之间的通信模型,在介绍这个通信模型的基础上,再
简单介绍实现这个模型所需要数据类型。
本文所介绍内容基于android2.2版本。由于android版本的不同,本文所包含的一些类可能在命名等细节上做了一些更改,但
万变不离其宗,整个核心思想和通信流程依旧如下。
例如,①、在android2.3上就将android2.2中ActivityManagerService的很多处理逻辑提炼出来,形成了一个单独的
ActivityStack类,因而显得更“高级”;
②、将后文讲解到的HistoryRecord.java直接重名名为ActivityRecord.java等。
很多不同点我也就不在细说了。大家在研究源码的过程里,注意差异就成。
Android的三大核心功能有如下三个:
1、View.java 关于View工作原理,《Android中View绘制流程以及invalidate()等相关方法分析》分析过。
功能有: 绘制图形、处理触摸、按键事件等;
2、ActivityManagerService.java 简称为 AMS
功能有:管理所有应用程序的Activity 、内存管理等 。
3、WindowManagerService.java 简称为WMS
功能有:为所有应用程序分配窗口,并管理这些窗口。
从上可知,AMS作为一种系统级服务管理所有Activity,当操作某个Activity时,例如: 启动一个新的Activity、停止当前
Activity,必须报告给AMS,而不能“擅自处理”。当AMS接受到具体通知时,会根据该通知的类型,首先会更新内部记录,
然后在通知相应客户进程去运行一个新的Activity或者停止指定的Activity。另外,由于AMS记录了所有Activity的信息,当然
能够主动的调度这些Activity,甚至在内存不足时,主动杀死后台的Activity。
首先对模型中可能运到的类做一个介绍:
ActivityThread.java 路径位于:\frameworks\base\core\java\android\app\ActivityThread.java
说明: 该类为应用程序(即APK包)所对应进程(一个进程里可能有多个应用程序)的主线程类,即我们通常所说的UI线程。
一个ActivityThread类对应于一个进程。最重要的是,每个应用程序的入口是该类中的static main()函数 。
Activity.java 路径位于:\frameworks\base\core\java\android\app\Activity.java
说明:该类是与用户交互的对象,同时也是APK应用程序运行的最小单元。ActivityThread类会根据用户的操作选择运行
哪个Activity。当前运行的Activity是出于resume状态(有且仅有一个),其他Activity出于pause或stop状态。
Instrumentation.java 路径位于 :\frameworks\base\core\java\android\app\ActivityThread.java
说明: 该类用于具体操作某个Activity的功能----单向(oneway)调用AMS以及统计、测量该应用程序的所有开销。
一个Instrumentation类对应于一个进程。每个Activity内部都有一个该Instrumentation对象的引用。
举个例子吧。
我们将我们应用程序比作一个四合院,那么Activity对应于四合院的人,ActivithThread对应于院子的主人----管理所有人,
Instrumentation对应于管家------受气的命,接受来自人(Activity/ActivithThread)的命令 ,去单向(oneway)调用AMS 。
ApplicationThread类是ActivityThread的内部类:
说明:该类是一个Binder类,即可实现跨进程通信。主要用于接受从AMS传递过来的消息,继而做相应处理。
ActivityManagerService.java 路径位于:
\frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
说明:该类是一个Binder类,即可实现跨进程通信。因此可以接受从客户端,例如Instrumentation、Context等调用过来的
信息。ActivityManagerService提供了全局的代理对象,供IPC调用。
AMS与ActivityThread的通信模型图如下:
从该模型图我们得知以下知识点:
第一、 引起调用AMS的对象通常有Context 、 Instrumentatio、ActivityThread等 。
第二、当AMS接受到来自某个应用程序传来的消息后,在AMS内部处理完毕后,会通过Binder机制回调回该应用程序
所在ApplicationThread服务端类,即ActivityThread.java类。
第三、当ActivityThread接受到AMS传递过来的消息后,进行内部处理。如果需要的话,会继续与AMS通信。
最后,当整个通信完成时,ActivityThread会选择合适的对象,例如Service、Activity、BroadcastReceiver等去做相应的
处理。
最后,对通信模型设计到的设计到的数据类进行介绍:
AMS 服务端用到的数据类:
ProcessRecord.java 路径: \frameworks\base\services\java\com\android\server\am\ ProcessRecord.java
说明: 记录每个进程的里的全部信息 。 主要信息包括该进程中包含的Activity、Provider、Service等信息、进程文件信息、
该进程的内存状态信息。
源代码(部分)如下:
- /**
- * Full information about a particular process that is currently running.
- */
- class ProcessRecord implements Watchdog.PssRequestor {
- // 第一个应用程序的ApplicationInfo对象
- final ApplicationInfo info; // all about the first app in the process
- final String processName; // name of the process 进程名
- // List of packages running in the process
- final HashSet<String> pkgList = new HashSet(); // 该进程里运行的应用程序包名
- // contains HistoryRecord objects
- final ArrayList activities = new ArrayList(); // 保存该进程下所有Activity的信息<activty
- // /> AndroidManifest.xml
- // all ServiceRecord running in this process
- final HashSet services = new HashSet(); // 保存该进程下所有Service的信息 <Service />
- }
HistoryRecord.java 路径:\frameworks\base\services\java\com\android\server\am\HistoryRecord.java
说明: 记录每个Activity的全部信息,因为AMS不知道客户端Activity的存在,因此在服务端用HistroyRecord对象来方便
管理和统计对应客户端Activity的信息。而且该类也是一个Binder类,因此可以跨进程调用。在客户端中,ActivityThread同样
用HistroyRecord的“代理“ Proxy对象去标记对应的Activity。
源代码(部分)如下:
- **
- * An entry in the history stack, representing an activity.
- */
- class HistoryRecord extends IApplicationToken.Stub {
- final ActivityInfo info; // all about me
- final Intent intent; // the original intent that generated us
- final String shortComponentName; // the short component name of the intent
- TaskRecord task; // the task this is in. 该Activity对应Task的信息
- ProcessRecord app; // if non-null, hosting application 该Activity所在的进程信息
- boolean stopped; // is activity pause finished? 该Activity是否已经停止 即onStop();
- boolean delayedResume; // not yet resumed because of stopped app switches? 是否需要暂时停止启动
- boolean finishing; // activity in pending finish list? 是否正在finish 即杀死该Activity
- ...
- }
TaskRecord.java 路径:\frameworks\base\services\java\com\android\server\am\TaskRecord.java
说明: 记录每个任务 Task的信息。 Activity可以运行在不同的Task中。
源代码(部分)如下:
- class TaskRecord {
- // id
- final int taskId; // Unique identifier for this task.
- final String affinity; // The affinity name for this task, or null.
- final boolean clearOnBackground; // As per the original activity.
- //启动一个新的Task的的Intent信息
- Intent intent; // The original intent that started the task.
- Intent affinityIntent; // Intent of affinity-moved activity that started this task.
- ComponentName origActivity; // The non-alias activity component of the intent.
- ComponentName realActivity; // The actual activity component that started the task.
- //运行在该Task的Activity数目
- int numActivities; // Current number of activities in this task.
- }
ActivityManagerService.java
PS:该类还是相当庞大的,有着琳琅满目的数据对象,稍不注意,就给迷失了。
源代码(部分)如下:
- class ActivityManagerService extends ActivityManagerNative implements xxx {
- // This is the maximum number of activities that we would like to have
- // running at a given time.
- static final int MAX_ACTIVITIES = 20; //系统中正在运行的Activity数目,最大为20
- // Maximum number of recent tasks that we can remember.
- static final int MAX_RECENT_TASKS = 20; //最大的Task数目为20
- /**
- * The back history of all previous (and possibly still
- * running) activities. It contains HistoryRecord objects.
- */ //当前系统中正在运行的Activity信息,即处于onPause、onStop、onResume状态的Activity信息
- final ArrayList mHistory = new ArrayList();
- /**
- * Current activity that is resumed, or null if there is none.
- */
- HistoryRecord mResumedActivity = null; //当前正在于用户交互的Activity信息,即处于onResume状态。
- /**
- * When we are in the process of pausing an activity, before starting the
- * next one, this variable holds the activity that is currently being paused.
- */
- HistoryRecord mPausingActivity = null; //当前正在暂停的Activity信息,即正在onPause();
- /**
- * All of the applications we currently have running organized by name.
- * The keys are strings of the application package name (as
- * returned by the package manager), and the keys are ApplicationRecord
- * objects.
- */ //当前正在运行的Process信息
- final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
- //开始启动一个Activity
- public final int startActivity(){ ...}
- }
ActivityThread所在客户端 :
基本对象都已在开篇介绍过,ActivityThread 、ApplicationThread 类。
ActivityThread .java
源代码(部分)如下:
- /**
- * This manages the execution of the main thread in an
- * application process, scheduling and executing activities,
- * broadcasts, and other operations on it as the activity
- * manager requests.
- *
- * {@hide}
- */
- public final class ActivityThread {
- //保存了该进程里所有正在运行的Activity信息 , 即没有onDestroy()的Activity
- //IBinder对象是HistoryRecord的代理对象,在客户端已IBinder标记每个Activity信息
- final HashMap<IBinder, ActivityRecord> mActivities = new HashMap<IBinder, ActivityRecord>();
- final H mH = new H(); // H对象 ,Handler子类
- Instrumentation mInstrumentation;
- ...
- }
ApplicationThread 是ActivityThread的内部类
源代码(部分)如下:
- public final class ActivityThread {
- ...
- //Binder类 主用功能是接受从AMS传递过来的消息,做处理后转发给H类去进一步处理。
- private final class ApplicationThread extends ApplicationThreadNative{
- public final void schedulePauseActivity(){...}
- public final void scheduleSendResult{...}
- public final void scheduleSendResult(){...}
- }
- }
最后介绍一下ActivityThread的两个内部类。
H类 是ActivityThread的内部类
说明 :H类是一个Hander子类 ,该类仅仅是为了异步调用而设计的,使用方法同Hander类一样。
源代码(部分)如下:
- public final class ActivityThread {
- ...
- private final class H extends Handler {
- private H() {
- SamplingProfiler.getInstance().setEventThread(mLooper.getThread());
- }
- //处理消息
- public void handleMessage(Message msg){
- switch (msg.what) {
- case LAUNCH_ACTIVITY: {
- //启动一个Activity
- ActivityRecord r = (ActivityRecord)msg.obj;
- r.packageInfo = getPackageInfoNoCheck(
- r.activityInfo.applicationInfo);
- handleLaunchActivity(r, null);
- }
- ...
- }
- }
- }
- }
ActivityRecord类同样是ActivityThread的内部类
说明:在客户端保存当前Activity的相关信息,方便ActivityThread管理维护Activity。这个类在实现和功能上对应于AMS的
HistoryRecord类。
源代码(部分)如下:
- <span style="font-size:16px;">public final class ActivityThread{
- ...
- //记录了客户端Activity的信息
- private static final class ActivityRecord {
- IBinder token; //该变量对应于AMS服务端HistoryRecord对象
- Intent intent; //启动该Activity对应的intent信息
- Bundle state; //保存一些信息 onCreate(state)
- Activity activity; //对应于Activity类
- ActivityInfo activityInfo; //对应的ActivityInfo对象
- ...
- }
- }</span>
另外我再对客户端Activity、ActivityRecord、ActivityThread 类包含的IBinder token属性进行一下说明:该token变量
实际上指向的的ActivityManagerService的HistoryRecord对象,他们是一一对应的。在应用程序内部和AMS都通过该token
变量来标记我们实际需要的Activity信息。 如下图所示:
对ActivityManagerService通信模型以及数据类有一定认识后,那么现在你就可以具体去接触每个操作是怎么实现的了。 例
如 startActivity()、 registerReceiver()等。 后面我也会慢慢讲解到的,有兴趣的可以先看如下两篇吧。讲解的都挺详细的,反正
我是偷了 不少经。 O(∩_∩)O~
Android核心分析(22)-----Android应用框架之Activity ( 基于android 2.2 版本)
Android应用程序启动过程源代码分析 ( 基于android 2.3 版本)
本文原创 ,转载必须注明出处 :http://blog.csdn.net/qinjuning
今天主要分析下ActivityManagerService(服务端) 与应用程序(客户端)之间的通信模型,在介绍这个通信模型的基础上,再
简单介绍实现这个模型所需要数据类型。
本文所介绍内容基于android2.2版本。由于android版本的不同,本文所包含的一些类可能在命名等细节上做了一些更改,但
万变不离其宗,整个核心思想和通信流程依旧如下。
例如,①、在android2.3上就将android2.2中ActivityManagerService的很多处理逻辑提炼出来,形成了一个单独的
ActivityStack类,因而显得更“高级”;
②、将后文讲解到的HistoryRecord.java直接重名名为ActivityRecord.java等。
很多不同点我也就不在细说了。大家在研究源码的过程里,注意差异就成。
Android的三大核心功能有如下三个:
1、View.java 关于View工作原理,《Android中View绘制流程以及invalidate()等相关方法分析》分析过。
功能有: 绘制图形、处理触摸、按键事件等;
2、ActivityManagerService.java 简称为 AMS
功能有:管理所有应用程序的Activity 、内存管理等 。
3、WindowManagerService.java 简称为WMS
功能有:为所有应用程序分配窗口,并管理这些窗口。
从上可知,AMS作为一种系统级服务管理所有Activity,当操作某个Activity时,例如: 启动一个新的Activity、停止当前
Activity,必须报告给AMS,而不能“擅自处理”。当AMS接受到具体通知时,会根据该通知的类型,首先会更新内部记录,
然后在通知相应客户进程去运行一个新的Activity或者停止指定的Activity。另外,由于AMS记录了所有Activity的信息,当然
能够主动的调度这些Activity,甚至在内存不足时,主动杀死后台的Activity。
首先对模型中可能运到的类做一个介绍:
ActivityThread.java 路径位于:\frameworks\base\core\java\android\app\ActivityThread.java
说明: 该类为应用程序(即APK包)所对应进程(一个进程里可能有多个应用程序)的主线程类,即我们通常所说的UI线程。
一个ActivityThread类对应于一个进程。最重要的是,每个应用程序的入口是该类中的static main()函数 。
Activity.java 路径位于:\frameworks\base\core\java\android\app\Activity.java
说明:该类是与用户交互的对象,同时也是APK应用程序运行的最小单元。ActivityThread类会根据用户的操作选择运行
哪个Activity。当前运行的Activity是出于resume状态(有且仅有一个),其他Activity出于pause或stop状态。
Instrumentation.java 路径位于 :\frameworks\base\core\java\android\app\ActivityThread.java
说明: 该类用于具体操作某个Activity的功能----单向(oneway)调用AMS以及统计、测量该应用程序的所有开销。
一个Instrumentation类对应于一个进程。每个Activity内部都有一个该Instrumentation对象的引用。
举个例子吧。
我们将我们应用程序比作一个四合院,那么Activity对应于四合院的人,ActivithThread对应于院子的主人----管理所有人,
Instrumentation对应于管家------受气的命,接受来自人(Activity/ActivithThread)的命令 ,去单向(oneway)调用AMS 。
ApplicationThread类是ActivityThread的内部类:
说明:该类是一个Binder类,即可实现跨进程通信。主要用于接受从AMS传递过来的消息,继而做相应处理。
ActivityManagerService.java 路径位于:
\frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
说明:该类是一个Binder类,即可实现跨进程通信。因此可以接受从客户端,例如Instrumentation、Context等调用过来的
信息。ActivityManagerService提供了全局的代理对象,供IPC调用。
AMS与ActivityThread的通信模型图如下:
从该模型图我们得知以下知识点:
第一、 引起调用AMS的对象通常有Context 、 Instrumentatio、ActivityThread等 。
第二、当AMS接受到来自某个应用程序传来的消息后,在AMS内部处理完毕后,会通过Binder机制回调回该应用程序
所在ApplicationThread服务端类,即ActivityThread.java类。
第三、当ActivityThread接受到AMS传递过来的消息后,进行内部处理。如果需要的话,会继续与AMS通信。
最后,当整个通信完成时,ActivityThread会选择合适的对象,例如Service、Activity、BroadcastReceiver等去做相应的
处理。
最后,对通信模型设计到的设计到的数据类进行介绍:
AMS 服务端用到的数据类:
ProcessRecord.java 路径: \frameworks\base\services\java\com\android\server\am\ ProcessRecord.java
说明: 记录每个进程的里的全部信息 。 主要信息包括该进程中包含的Activity、Provider、Service等信息、进程文件信息、
该进程的内存状态信息。
源代码(部分)如下:
- /**
- * Full information about a particular process that is currently running.
- */
- class ProcessRecord implements Watchdog.PssRequestor {
- // 第一个应用程序的ApplicationInfo对象
- final ApplicationInfo info; // all about the first app in the process
- final String processName; // name of the process 进程名
- // List of packages running in the process
- final HashSet<String> pkgList = new HashSet(); // 该进程里运行的应用程序包名
- // contains HistoryRecord objects
- final ArrayList activities = new ArrayList(); // 保存该进程下所有Activity的信息<activty
- // /> AndroidManifest.xml
- // all ServiceRecord running in this process
- final HashSet services = new HashSet(); // 保存该进程下所有Service的信息 <Service />
- }
HistoryRecord.java 路径:\frameworks\base\services\java\com\android\server\am\HistoryRecord.java
说明: 记录每个Activity的全部信息,因为AMS不知道客户端Activity的存在,因此在服务端用HistroyRecord对象来方便
管理和统计对应客户端Activity的信息。而且该类也是一个Binder类,因此可以跨进程调用。在客户端中,ActivityThread同样
用HistroyRecord的“代理“ Proxy对象去标记对应的Activity。
源代码(部分)如下:
- **
- * An entry in the history stack, representing an activity.
- */
- class HistoryRecord extends IApplicationToken.Stub {
- final ActivityInfo info; // all about me
- final Intent intent; // the original intent that generated us
- final String shortComponentName; // the short component name of the intent
- TaskRecord task; // the task this is in. 该Activity对应Task的信息
- ProcessRecord app; // if non-null, hosting application 该Activity所在的进程信息
- boolean stopped; // is activity pause finished? 该Activity是否已经停止 即onStop();
- boolean delayedResume; // not yet resumed because of stopped app switches? 是否需要暂时停止启动
- boolean finishing; // activity in pending finish list? 是否正在finish 即杀死该Activity
- ...
- }
TaskRecord.java 路径:\frameworks\base\services\java\com\android\server\am\TaskRecord.java
说明: 记录每个任务 Task的信息。 Activity可以运行在不同的Task中。
源代码(部分)如下:
- class TaskRecord {
- // id
- final int taskId; // Unique identifier for this task.
- final String affinity; // The affinity name for this task, or null.
- final boolean clearOnBackground; // As per the original activity.
- //启动一个新的Task的的Intent信息
- Intent intent; // The original intent that started the task.
- Intent affinityIntent; // Intent of affinity-moved activity that started this task.
- ComponentName origActivity; // The non-alias activity component of the intent.
- ComponentName realActivity; // The actual activity component that started the task.
- //运行在该Task的Activity数目
- int numActivities; // Current number of activities in this task.
- }
ActivityManagerService.java
PS:该类还是相当庞大的,有着琳琅满目的数据对象,稍不注意,就给迷失了。
源代码(部分)如下:
- class ActivityManagerService extends ActivityManagerNative implements xxx {
- // This is the maximum number of activities that we would like to have
- // running at a given time.
- static final int MAX_ACTIVITIES = 20; //系统中正在运行的Activity数目,最大为20
- // Maximum number of recent tasks that we can remember.
- static final int MAX_RECENT_TASKS = 20; //最大的Task数目为20
- /**
- * The back history of all previous (and possibly still
- * running) activities. It contains HistoryRecord objects.
- */ //当前系统中正在运行的Activity信息,即处于onPause、onStop、onResume状态的Activity信息
- final ArrayList mHistory = new ArrayList();
- /**
- * Current activity that is resumed, or null if there is none.
- */
- HistoryRecord mResumedActivity = null; //当前正在于用户交互的Activity信息,即处于onResume状态。
- /**
- * When we are in the process of pausing an activity, before starting the
- * next one, this variable holds the activity that is currently being paused.
- */
- HistoryRecord mPausingActivity = null; //当前正在暂停的Activity信息,即正在onPause();
- /**
- * All of the applications we currently have running organized by name.
- * The keys are strings of the application package name (as
- * returned by the package manager), and the keys are ApplicationRecord
- * objects.
- */ //当前正在运行的Process信息
- final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
- //开始启动一个Activity
- public final int startActivity(){ ...}
- }
ActivityThread所在客户端 :
基本对象都已在开篇介绍过,ActivityThread 、ApplicationThread 类。
ActivityThread .java
源代码(部分)如下:
- /**
- * This manages the execution of the main thread in an
- * application process, scheduling and executing activities,
- * broadcasts, and other operations on it as the activity
- * manager requests.
- *
- * {@hide}
- */
- public final class ActivityThread {
- //保存了该进程里所有正在运行的Activity信息 , 即没有onDestroy()的Activity
- //IBinder对象是HistoryRecord的代理对象,在客户端已IBinder标记每个Activity信息
- final HashMap<IBinder, ActivityRecord> mActivities = new HashMap<IBinder, ActivityRecord>();
- final H mH = new H(); // H对象 ,Handler子类
- Instrumentation mInstrumentation;
- ...
- }
ApplicationThread 是ActivityThread的内部类
源代码(部分)如下:
- public final class ActivityThread {
- ...
- //Binder类 主用功能是接受从AMS传递过来的消息,做处理后转发给H类去进一步处理。
- private final class ApplicationThread extends ApplicationThreadNative{
- public final void schedulePauseActivity(){...}
- public final void scheduleSendResult{...}
- public final void scheduleSendResult(){...}
- }
- }
最后介绍一下ActivityThread的两个内部类。
H类 是ActivityThread的内部类
说明 :H类是一个Hander子类 ,该类仅仅是为了异步调用而设计的,使用方法同Hander类一样。
源代码(部分)如下:
- public final class ActivityThread {
- ...
- private final class H extends Handler {
- private H() {
- SamplingProfiler.getInstance().setEventThread(mLooper.getThread());
- }
- //处理消息
- public void handleMessage(Message msg){
- switch (msg.what) {
- case LAUNCH_ACTIVITY: {
- //启动一个Activity
- ActivityRecord r = (ActivityRecord)msg.obj;
- r.packageInfo = getPackageInfoNoCheck(
- r.activityInfo.applicationInfo);
- handleLaunchActivity(r, null);
- }
- ...
- }
- }
- }
- }
ActivityRecord类同样是ActivityThread的内部类
说明:在客户端保存当前Activity的相关信息,方便ActivityThread管理维护Activity。这个类在实现和功能上对应于AMS的
HistoryRecord类。
源代码(部分)如下:
- <span style="font-size:16px;">public final class ActivityThread{
- ...
- //记录了客户端Activity的信息
- private static final class ActivityRecord {
- IBinder token; //该变量对应于AMS服务端HistoryRecord对象
- Intent intent; //启动该Activity对应的intent信息
- Bundle state; //保存一些信息 onCreate(state)
- Activity activity; //对应于Activity类
- ActivityInfo activityInfo; //对应的ActivityInfo对象
- ...
- }
- }</span>
另外我再对客户端Activity、ActivityRecord、ActivityThread 类包含的IBinder token属性进行一下说明:该token变量
实际上指向的的ActivityManagerService的HistoryRecord对象,他们是一一对应的。在应用程序内部和AMS都通过该token
变量来标记我们实际需要的Activity信息。 如下图所示:
对ActivityManagerService通信模型以及数据类有一定认识后,那么现在你就可以具体去接触每个操作是怎么实现的了。 例
如 startActivity()、 registerReceiver()等。 后面我也会慢慢讲解到的,有兴趣的可以先看如下两篇吧。讲解的都挺详细的,反正
我是偷了 不少经。 O(∩_∩)O~
Android核心分析(22)-----Android应用框架之Activity ( 基于android 2.2 版本)
Android应用程序启动过程源代码分析 ( 基于android 2.3 版本)