今天主要分析下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等信息、进程文件信息、

该进程的内存状态信息。

源代码(部分)如下:

[java] view plaincopyprint?
  1. /**
  2. * Full information about a particular process that is currently running.
  3. */
  4. class ProcessRecord implements Watchdog.PssRequestor {
  5. // 第一个应用程序的ApplicationInfo对象
  6. final ApplicationInfo info; // all about the first app in the process
  7. final String processName; // name of the process 进程名
  8. // List of packages running in the process
  9. final HashSet<String> pkgList = new HashSet(); // 该进程里运行的应用程序包名
  10. // contains HistoryRecord objects
  11. final ArrayList activities = new ArrayList(); // 保存该进程下所有Activity的信息<activty
  12. // /> AndroidManifest.xml
  13. // all ServiceRecord running in this process
  14. final HashSet services = new HashSet(); // 保存该进程下所有Service的信息 <Service />
  15. }

HistoryRecord.java   路径:\frameworks\base\services\java\com\android\server\am\HistoryRecord.java

说明: 记录每个Activity的全部信息,因为AMS不知道客户端Activity的存在,因此在服务端用HistroyRecord对象来方便

管理和统计对应客户端Activity的信息。而且该类也是一个Binder类,因此可以跨进程调用。在客户端中,ActivityThread同样

用HistroyRecord的“代理“ Proxy对象去标记对应的Activity。

源代码(部分)如下:

[java] view plaincopyprint?
  1. **
  2. * An entry in the history stack, representing an activity.
  3. */
  4. class HistoryRecord extends IApplicationToken.Stub {
  5. final ActivityInfo info; // all about me
  6. final Intent intent; // the original intent that generated us
  7. final String shortComponentName; // the short component name of the intent
  8. TaskRecord task;        // the task this is in.  该Activity对应Task的信息
  9. ProcessRecord app;  // if non-null, hosting application 该Activity所在的进程信息
  10. boolean stopped;        // is activity pause finished?  该Activity是否已经停止 即onStop();
  11. boolean delayedResume;  // not yet resumed because of stopped app switches? 是否需要暂时停止启动
  12. boolean finishing;      // activity in pending finish list?  是否正在finish 即杀死该Activity
  13. ...
  14. }

   TaskRecord.java       路径:\frameworks\base\services\java\com\android\server\am\TaskRecord.java

说明: 记录每个任务 Task的信息。 Activity可以运行在不同的Task中。

源代码(部分)如下:

[java] view plaincopyprint?
  1. class TaskRecord {
  2. // id
  3. final int taskId;       // Unique identifier for this task.
  4. final String affinity;  // The affinity name for this task, or null.
  5. final boolean clearOnBackground; // As per the original activity.
  6. //启动一个新的Task的的Intent信息
  7. Intent intent;          // The original intent that started the task.
  8. Intent affinityIntent;  // Intent of affinity-moved activity that started this task.
  9. ComponentName origActivity; // The non-alias activity component of the intent.
  10. ComponentName realActivity; // The actual activity component that started the task.
  11. //运行在该Task的Activity数目
  12. int numActivities;      // Current number of activities in this task.
  13. }

ActivityManagerService.java

PS:该类还是相当庞大的,有着琳琅满目的数据对象,稍不注意,就给迷失了。

源代码(部分)如下:

[java] view plaincopyprint?
  1. class ActivityManagerService extends ActivityManagerNative implements xxx {
  2. // This is the maximum number of activities that we would like to have
  3. // running at a given time.
  4. static final int MAX_ACTIVITIES = 20;  //系统中正在运行的Activity数目,最大为20
  5. // Maximum number of recent tasks that we can remember.
  6. static final int MAX_RECENT_TASKS = 20; //最大的Task数目为20
  7. /**
  8. * The back history of all previous (and possibly still
  9. * running) activities.  It contains HistoryRecord objects.
  10. */  //当前系统中正在运行的Activity信息,即处于onPause、onStop、onResume状态的Activity信息
  11. final ArrayList mHistory = new ArrayList();
  12. /**
  13. * Current activity that is resumed, or null if there is none.
  14. */
  15. HistoryRecord mResumedActivity = null;  //当前正在于用户交互的Activity信息,即处于onResume状态。
  16. /**
  17. * When we are in the process of pausing an activity, before starting the
  18. * next one, this variable holds the activity that is currently being paused.
  19. */
  20. HistoryRecord mPausingActivity = null;  //当前正在暂停的Activity信息,即正在onPause();
  21. /**
  22. * All of the applications we currently have running organized by name.
  23. * The keys are strings of the application package name (as
  24. * returned by the package manager), and the keys are ApplicationRecord
  25. * objects.
  26. */  //当前正在运行的Process信息
  27. final ProcessMap<ProcessRecord> mProcessNames  = new ProcessMap<ProcessRecord>();
  28. //开始启动一个Activity
  29. public final int startActivity(){ ...}
  30. }

ActivityThread所在客户端 :

基本对象都已在开篇介绍过,ActivityThread 、ApplicationThread 类。

  ActivityThread .java 

源代码(部分)如下:

[java] view plaincopyprint?
  1. /**
  2. * This manages the execution of the main thread in an
  3. * application process, scheduling and executing activities,
  4. * broadcasts, and other operations on it as the activity
  5. * manager requests.
  6. *
  7. * {@hide}
  8. */
  9. public final class ActivityThread {
  10. //保存了该进程里所有正在运行的Activity信息  , 即没有onDestroy()的Activity
  11. //IBinder对象是HistoryRecord的代理对象,在客户端已IBinder标记每个Activity信息
  12. final HashMap<IBinder, ActivityRecord> mActivities = new HashMap<IBinder, ActivityRecord>();
  13. final H mH = new H();  // H对象 ,Handler子类
  14. Instrumentation mInstrumentation;
  15. ...
  16. }

  ApplicationThread    是ActivityThread的内部类

源代码(部分)如下:

[java] view plaincopyprint?
  1. public final class ActivityThread {
  2. ...
  3. //Binder类 主用功能是接受从AMS传递过来的消息,做处理后转发给H类去进一步处理。
  4. private final class ApplicationThread extends ApplicationThreadNative{
  5. public final void schedulePauseActivity(){...}
  6. public final void scheduleSendResult{...}
  7. public final void scheduleSendResult(){...}
  8. }
  9. }

最后介绍一下ActivityThread的两个内部类。

H类      是ActivityThread的内部类

说明 :H类是一个Hander子类 ,该类仅仅是为了异步调用而设计的,使用方法同Hander类一样。

源代码(部分)如下:

[java] view plaincopyprint?
  1. public final class ActivityThread {
  2. ...
  3. private final class H extends Handler {
  4. private H() {
  5. SamplingProfiler.getInstance().setEventThread(mLooper.getThread());
  6. }
  7. //处理消息
  8. public void handleMessage(Message msg){
  9. switch (msg.what) {
  10. case LAUNCH_ACTIVITY: {
  11. //启动一个Activity
  12. ActivityRecord r = (ActivityRecord)msg.obj;
  13. r.packageInfo = getPackageInfoNoCheck(
  14. r.activityInfo.applicationInfo);
  15. handleLaunchActivity(r, null);
  16. }
  17. ...
  18. }
  19. }
  20. }
  21. }

ActivityRecord类同样是ActivityThread的内部类

说明:在客户端保存当前Activity的相关信息,方便ActivityThread管理维护Activity。这个类在实现和功能上对应于AMS的

HistoryRecord类。

源代码(部分)如下:

[java] view plaincopyprint?
  1. <span style="font-size:16px;">public final class ActivityThread{
  2. ...
  3. //记录了客户端Activity的信息
  4. private static final class ActivityRecord {
  5. IBinder token;  //该变量对应于AMS服务端HistoryRecord对象
  6. Intent intent;  //启动该Activity对应的intent信息
  7. Bundle state;   //保存一些信息  onCreate(state)
  8. Activity activity;  //对应于Activity类
  9. ActivityInfo activityInfo;  //对应的ActivityInfo对象
  10. ...
  11. }
  12. }</span>

另外我再对客户端Activity、ActivityRecord、ActivityThread 类包含的IBinder token属性进行一下说明:该token变量

实际上指向的的ActivityManagerService的HistoryRecord对象,他们是一一对应的。在应用程序内部和AMS都通过该token

变量来标记我们实际需要的Activity信息。 如下图所示:

对ActivityManagerService通信模型以及数据类有一定认识后,那么现在你就可以具体去接触每个操作是怎么实现的了。 例

如 startActivity()、 registerReceiver()等。 后面我也会慢慢讲解到的,有兴趣的可以先看如下两篇吧。讲解的都挺详细的,反正

我是偷了 不少经。 O(∩_∩)O~

Android中ActivityManagerService与应用程序(客户端)通信模型分析相关推荐

  1. java商城项目中多线程执行_java多线程中执行多个程序的实例分析

    我们知道多线程因为同时处理子线程的能力,对于程序运行来说,能够达到很高的效率.不过很多人对于多线程的执行方法还没有尝试过,本篇我们将为大家介绍创建线程的方法,在这个基础上,对程序执行多条命令的方法进行 ...

  2. Android中XML的三种解析器分析、实战

    XML解析器介绍 Android中提供了三种方式来解析XML: SAX(simple API for XML) DOM(文档对象模型) 以及Android内部使用的Pull解析. SAX(simple ...

  3. android中的计步问题及计步传感器分析

    今天打开博客,才发现居然有一年多没有写博客了... 最近由于公司要分析android上的计步问题,顺便把计步器在android上的实现跟踪了一下.结果发现悲催的是,android的api19上,是用的 ...

  4. android中app分享小程序卡片及跳转回app

    随着小程序的日渐火热,许多app都做了相应的小程序端,与之而来的两端交互是必不可少的,前几天我们的分享到微信的样式也要求改成了小程序卡片样式的了.其实微信的官方文档还算比较详细,我这就结合自己踩的坑给 ...

  5. 多个android手机客户端通信,android中利用Socket实现手机客户端与PC端进行通信

    服务器端: import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; impo ...

  6. android 安装包 权限,确定Android中已安装应用程序使用的权限列表

    我必须确定我的设备上已安装的应用程序使用的权限列表. 我已经安装了应用程序列表,并使用以下代码包名称: PackageManager pm = this.getPackageManager(); In ...

  7. Android中在自己的程序中打开另一个apk(应用)

    最近开发一款智能电视上的应用,有播放网络视频的功能.因为是第一版项目,所以被没有自己去开发播放功能,只是集成一个叫泰捷视频apk,在那个apk功能就是播放网络视频的. 这里就需要用到在我写的程序中去打 ...

  8. android中获取某段程序的执行时间

    Date   startDate   =   new   Date(System.currentTimeMillis()); 在收到设备返回数据之后添加如下语句: Date   endDate   = ...

  9. Android中Google Drive显示黑屏问题分析

    一.问题现象 在contacts中添加一个新的联系人,为新的联系人选择一个icon,在弹出的documents窗口中选择drive,在drive中选择一个图片,然后出现一段时间的黑屏. Platfor ...

最新文章

  1. 知乎服务化的实践与思考
  2. 前端(jQuery)(5)-- jQuery AJAX异步访问和加载片段
  3. Event Aggregator
  4. boost::graph模块实现closeness中心性的测试程序
  5. P3952 时间复杂度(模拟)
  6. 从css样式表中抽取元素尺寸
  7. java 第十一章总结
  8. mysql索引创建及使用注意事项
  9. 周杰伦新歌《说好不哭》上线,程序员哭了......【华为云分享】
  10. 【转】关于Class.forName(“com.mysql.jdbc.Driver”)
  11. Unix环境高级编程笔记:12、高级IO
  12. 【bzoj1022】[SHOI2008]小约翰的游戏John 博弈论
  13. 强强联手,AliOS和ACRN为物联网领域带来全新解决方案
  14. matlab的yalmip为什么这么慢,Yalmip使用学习
  15. 浏览器transform介绍
  16. oracle数据库数值函数,oracle数据库函数对照表
  17. java取上一个月_Java获取指定日期前一月(年)或后一月(年)
  18. Shell脚本:循环for / while / until
  19. chrome新版不支持旺旺 支付宝 插件的解决方法
  20. 刷脸支付会员积分卡券打造完整商业闭环

热门文章

  1. 【错误记录】NDK 导入外部 so 动态库报错 ( java.lang.UnsatisfiedLinkError | Android Studio 配置外部 so 动态库两种方法 )
  2. 【Android 安全】DEX 加密 ( Application 替换 | 分析 Service 组件中调用 getApplication() 获取的 Application 是否替换成功 )
  3. 【RecyclerView】 八、RecyclerView.ItemDecoration 条目装饰 ( onDraw 和 onDrawOver 绘制要点 )
  4. HDU 5693 D Game 区间dp
  5. 前端小问题1——(最近好久没有发博客。。。待续)
  6. 获取一个对象的属性/属性值,以及动态给属性赋值
  7. 设为首页及收藏本页代码 兼容IE和Firefox
  8. 微信小程序开发--如何在swiper中显示两个item以及下一个item的部分内容
  9. LeetCode算法题12:递归和回溯-字符串中的回溯问题
  10. 前端JS: 通过代码-看函数作用域this对象