今天主要分析下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 plain copy print ?
  1. /**
  2. *Fullinformationaboutaparticularprocessthatiscurrentlyrunning.
  3. */
  4. classProcessRecordimplementsWatchdog.PssRequestor{
  5. //第一个应用程序的ApplicationInfo对象
  6. finalApplicationInfoinfo;//allaboutthefirstappintheprocess
  7. finalStringprocessName;//nameoftheprocess进程名
  8. //Listofpackagesrunningintheprocess
  9. finalHashSet<String>pkgList=newHashSet();//该进程里运行的应用程序包名
  10. //containsHistoryRecordobjects
  11. finalArrayListactivities=newArrayList();//保存该进程下所有Activity的信息<activty
  12. ///>AndroidManifest.xml
  13. //allServiceRecordrunninginthisprocess
  14. finalHashSetservices=newHashSet();//保存该进程下所有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 plain copy print ?
  1. **
  2. *Anentryinthehistorystack,representinganactivity.
  3. */
  4. classHistoryRecordextendsIApplicationToken.Stub{
  5. finalActivityInfoinfo;//allaboutme
  6. finalIntentintent;//theoriginalintentthatgeneratedus
  7. finalStringshortComponentName;//theshortcomponentnameoftheintent
  8. TaskRecordtask;//thetaskthisisin.该Activity对应Task的信息
  9. ProcessRecordapp;//ifnon-null,hostingapplication该Activity所在的进程信息
  10. booleanstopped;//isactivitypausefinished?该Activity是否已经停止即onStop();
  11. booleandelayedResume;//notyetresumedbecauseofstoppedappswitches?是否需要暂时停止启动
  12. booleanfinishing;//activityinpendingfinishlist?是否正在finish即杀死该Activity
  13. ...
  14. }

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

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

源代码(部分)如下:

[java] view plain copy print ?
  1. classTaskRecord{
  2. //id
  3. finalinttaskId;//Uniqueidentifierforthistask.
  4. finalStringaffinity;//Theaffinitynameforthistask,ornull.
  5. finalbooleanclearOnBackground;//Aspertheoriginalactivity.
  6. //启动一个新的Task的的Intent信息
  7. Intentintent;//Theoriginalintentthatstartedthetask.
  8. IntentaffinityIntent;//Intentofaffinity-movedactivitythatstartedthistask.
  9. ComponentNameorigActivity;//Thenon-aliasactivitycomponentoftheintent.
  10. ComponentNamerealActivity;//Theactualactivitycomponentthatstartedthetask.
  11. //运行在该Task的Activity数目
  12. intnumActivities;//Currentnumberofactivitiesinthistask.
  13. }

ActivityManagerService.java

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

源代码(部分)如下:

[java] view plain copy print ?
  1. classActivityManagerServiceextendsActivityManagerNativeimplementsxxx{
  2. //Thisisthemaximumnumberofactivitiesthatwewouldliketohave
  3. //runningatagiventime.
  4. staticfinalintMAX_ACTIVITIES=20;//系统中正在运行的Activity数目,最大为20
  5. //Maximumnumberofrecenttasksthatwecanremember.
  6. staticfinalintMAX_RECENT_TASKS=20;//最大的Task数目为20
  7. /**
  8. *Thebackhistoryofallprevious(andpossiblystill
  9. *running)activities.ItcontainsHistoryRecordobjects.
  10. *///当前系统中正在运行的Activity信息,即处于onPause、onStop、onResume状态的Activity信息
  11. finalArrayListmHistory=newArrayList();
  12. /**
  13. *Currentactivitythatisresumed,ornullifthereisnone.
  14. */
  15. HistoryRecordmResumedActivity=null;//当前正在于用户交互的Activity信息,即处于onResume状态。
  16. /**
  17. *Whenweareintheprocessofpausinganactivity,beforestartingthe
  18. *nextone,thisvariableholdstheactivitythatiscurrentlybeingpaused.
  19. */
  20. HistoryRecordmPausingActivity=null;//当前正在暂停的Activity信息,即正在onPause();
  21. /**
  22. *Alloftheapplicationswecurrentlyhaverunningorganizedbyname.
  23. *Thekeysarestringsoftheapplicationpackagename(as
  24. *returnedbythepackagemanager),andthekeysareApplicationRecord
  25. *objects.
  26. *///当前正在运行的Process信息
  27. finalProcessMap<ProcessRecord>mProcessNames=newProcessMap<ProcessRecord>();
  28. //开始启动一个Activity
  29. publicfinalintstartActivity(){...}
  30. }

ActivityThread所在客户端 :

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

ActivityThread .java

源代码(部分)如下:

[java] view plain copy print ?
  1. /**
  2. *Thismanagestheexecutionofthemainthreadinan
  3. *applicationprocess,schedulingandexecutingactivities,
  4. *broadcasts,andotheroperationsonitastheactivity
  5. *managerrequests.
  6. *
  7. *{@hide}
  8. */
  9. publicfinalclassActivityThread{
  10. //保存了该进程里所有正在运行的Activity信息,即没有onDestroy()的Activity
  11. //IBinder对象是HistoryRecord的代理对象,在客户端已IBinder标记每个Activity信息
  12. finalHashMap<IBinder,ActivityRecord>mActivities=newHashMap<IBinder,ActivityRecord>();
  13. finalHmH=newH();//H对象,Handler子类
  14. InstrumentationmInstrumentation;
  15. ...
  16. }

ApplicationThread是ActivityThread的内部类

源代码(部分)如下:

[java] view plain copy print ?
  1. publicfinalclassActivityThread{
  2. ...
  3. //Binder类主用功能是接受从AMS传递过来的消息,做处理后转发给H类去进一步处理。
  4. privatefinalclassApplicationThreadextendsApplicationThreadNative{
  5. publicfinalvoidschedulePauseActivity(){...}
  6. publicfinalvoidscheduleSendResult{...}
  7. publicfinalvoidscheduleSendResult(){...}
  8. }
  9. }


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

H类 是ActivityThread的内部类

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

源代码(部分)如下:

[java] view plain copy print ?
  1. publicfinalclassActivityThread{
  2. ...
  3. privatefinalclassHextendsHandler{
  4. privateH(){
  5. SamplingProfiler.getInstance().setEventThread(mLooper.getThread());
  6. }
  7. //处理消息
  8. publicvoidhandleMessage(Messagemsg){
  9. switch(msg.what){
  10. caseLAUNCH_ACTIVITY:{
  11. //启动一个Activity
  12. ActivityRecordr=(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 plain copy print ?
  1. <spanstyle="font-size:16px;">publicfinalclassActivityThread{
  2. ...
  3. //记录了客户端Activity的信息
  4. privatestaticfinalclassActivityRecord{
  5. IBindertoken;//该变量对应于AMS服务端HistoryRecord对象
  6. Intentintent;//启动该Activity对应的intent信息
  7. Bundlestate;//保存一些信息onCreate(state)
  8. Activityactivity;//对应于Activity类
  9. ActivityInfoactivityInfo;//对应的ActivityInfo对象
  10. ...
  11. }
  12. }</span>

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

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

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

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

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

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



更多相关文章

  1. Android创建和使用数据库SQLIte
  2. Android---45---使用AIDL Service传递复杂数据
  3. Android(安卓)OOM 解决方案
  4. 面试准备android(一)
  5. Android入门进阶教程(14)-Binder进程通信介绍
  6. Android(安卓)DRM解析
  7. Android通过Servlet连接MySQL 实现登陆/注册(数据库+服务器+客户
  8. Android(安卓)JNI编程提高篇之二
  9. 深入解析RxJava源码(一)Observable对象的构建

随机推荐

  1. UE4-打包安卓报错 /Android/APK\gradle
  2. Android中实现听筒中播放声音
  3. Android(安卓)5.0以上加slidingmenu后页
  4. Android(安卓)打包过程
  5. 实现如何Android(安卓)获得图片的总结
  6. adb常用命令
  7. Android(安卓)利用Handle 切换的主线程更
  8. Android(安卓)scrollview实现底部继续拖
  9. Android调用自带TTS文本转语音引擎实现离
  10. android 原生附加业务UI代码和灰显逻辑。