前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android进阶解密:探访AMS家族

Android进阶解密:探访AMS家族

作者头像
用户1682855
发布2018-10-22 14:33:18
1.9K0
发布2018-10-22 14:33:18
举报
文章被收录于专栏:前沿技墅前沿技墅

本文作者 刘望舒

资深开发工程师,Android进阶二部曲《Android进阶之光》《Android进阶解密》的作者,公众号“刘望舒”的作者,CSDN人气博主。他在博客中构建了“Android相关原创知识体系”,该体系全面且深入并广获好评。他拥有近10年的开发经验和多年的技术管理经验,对Android框架层及应用层开发有着独到、深入的理解。

AMS处理的逻辑多而复杂,因此AMS并不是“孤军奋战”,而是有一些类和它“共同奋战”,这些类会帮助AMS完成相关逻辑,AMS和这些“共同奋战”的类就被称为AMS家族。Android 7.0和Android 8.0对于AMS相关部分的处理有较大的区别,为了更好地理解AMS家族,这里将分别介绍Android 7.0和Android 8.0的AMS家族。

Android 7.0的AMS家族

ActivityManager是一个和AMS相关联的类,它主要对运行中的Activity进行管理,这些管理工作并不是由ActivityManager来处理的,而是交由AMS来处理的。一般而言,ActivityManager 中的方法是会通过ActivityManagerNative(下面简称AMN)的getDefault方法来得到ActivityManagerProxy(下面简称 AMP ),通过 AMP 就可以和AMN进行通信,而AMN是一个抽象类,它将功能交由它的子类AMS来处理,因此,AMP就是AMS的代理类。AMS作为系统服务,很多API是不会暴露给ActivityManager的,因此ActivityManager并不算是AMS家族的一份子。为了讲解AMS家族,这里以Android 7.0的Activity启动过程来举例,在Activity的启动过程中会调用Instrumentation的execStartActivity方法,如下所示:

在execStartActivity方法中会调用AMN的getDefault方法来获取 AMS 的代理类 AMP ,接着调用了 AMP 的startActivity方法。下面先来查看AMN的getDefault方法做了什么,如下所示:

在getDefault方法中调用了gDefault的get方法,接着往下看,gDefault是一个Singleton类。在注释1处得到名为“activity”的Service引用,也就是IBinder类型的AMS的引用。然后在注释2处将它封装成AMP类型对象,并将它保存到 gDefault 中,此后调用 AMN 的getDefault方法就会直接获得AMS的代理对象AMP。注释2处的asInterface方法如下所示:

android.app.IActivityManager为注释1处的descriptor值,注释1处的代码主要用来查询本地进程是否有IActivityManager接口的实现。如果有,则返回;如果没有,就在注释2处将IBinder类型的AMS引用封装成AMP,AMP的构造方法如下所示:

在 AMP 的构造方法中,将 AMS 的引用赋值给变量mRemote,这样在AMP中就可以使用AMS了。其中IActivityManager是一个接口,AMN和AMP都有这个接口,用于实现代理模式以及 Binder 通信。再回到Instrumentation的execStartActivity方法,来查看AMP的startActivity方法,AMP是AMN的内部类,代码如下所示:

首先将传入的参数写入Parcel类型的data中。在注释1处,通过IBinder类型对象mRemote(AMS的引用)向服务器端的 AMS 发送一个进程间通信请求,类型则为START_ACTIVITY_TRANSACTION。那么服务器端AMS就会从Binder线程池中读取客户端发来的数据,最终会调用AMN的onTransact方法,如下所示:

在onTransact方法中会调用AMS的startActivity方法,如下所示:

startActivity方法最后会返回startActivityAsUser方法,如下所示:

startActivityAsUser方法最后会返回ActivityStarter的startActivityMayWait方法,这一调用过程已经脱离了本节要介绍的AMS家族的范畴,因此这里不做赘述了,具体的调用过程,则可以查看 4.1.2 节的内容。在Activity的启动过程中提到AMP、AMN和AMS,它们共同组成了AMS家族的主要部分,如图1所示。

图1 Android 7.0 AMS家族

AMP是AMN的内部类,都实现了IActivityManager接口,这样它们就可以实现代理模式,具体来讲就是远程代理:AMP和AMN是运行在两个进程中的,AMP是Client端,AMN则是Server端,而Server端中具体的功能都是由AMN的子类AMS来实现的。因此AMP就是AMS在Client端的代理类。AMN又实现了Binder类,这样AMP和AMS就可以通过Binder来进行进程间通信。ActivityManager通过AMN的getDefault方法得到AMP,通过 AMP 我们就可以和AMS进行通信。除ActivityManager以外,有些想要与AMS进行通信的类也需要通过AMP,如图2所示。

图2 AMP和AMS进行通信

从图2看出,除ActivityManager外, ContextImpl如果想要和AMS进行通信也需要先经过AMP。

Android 8.0的AMS家族

Android 8.0的AMS家族与Android 7.0有一些区别,为了更好地理解这些区别,我们仍旧以Activity启动过程来举例,只不过现在系统版本是Android 8.0,在Activity的启动过程中会调用Instrumentation的execStartActivity方法,如下所示:

ActivityManager的getService方法,如下所示:

IActivityManagerSingleton 是一个Singleton类,getService方法调用了它的get方法。在注释1处得到名为“activity”的Service引用,也就是IBinder类型的AMS的引用。接着,我们可在注释2处将它转换成IActivityManager类型的对象。注意,这段代码采用AIDL。IActivityManager.java类是由AIDL工具在编译时自动生成,IActivityManager.aidl的文件路径为frameworks/base/core/java/android/app/IActivityManager.aidl。要实现进程间通信,服务器端(也就是AMS)只需要继承IActivityManager.Stub类并实现相应的方法就可以了。采用AIDL后就不需要使用AMS的代理类AMP了,因此Android 8.0去掉了AMP,代替它的是IActivityManager,它是AMS在本地的代理。让我们再一次回到 Instrumentation 的execStartActivity方法,在注释1处实际上调用的是AMS的execStartActivity方法。剩下的调用过程就不再介绍了,我们来查看Android 8.0的AMS家族,如图3所示。

图3 Android 8.0 AMS家族

对比图3和图1,可以发现Android 8.0 AMS家族要简单得多,ActivityManager 的 getService 方法会得到 IActivityManager。正因如此,AMS只需要继承IActivityManager.Stub类,就可以方便地和ActivityManager实现进程间通信了。

————

本文节选自《Android进阶解密》一书。作为“Android进阶系列”的第二部,本书是继畅销书《Android进阶之光》之后,刘望舒的又一力作!本书基于Android 8.0,将系统源码和应用开发结合讲解,帮助读者融会贯通,破解Android应用开发进阶秘密。阅读原文将带你抢先一睹这本由安卓名家何红辉、徐宜生 、何俊林、潘辰星、周泰良、杨强、Tamic及安卓巴士技术社区联袂力荐的烫手新书。

  • 内容简介:本书是一本Android进阶书籍,主要针对Android 8.0系统源码并结合应用开发相关知识进行介绍。本书共分为17章,从3个方面来组织内容。第一方面介绍Android应用开发所需要掌握的系统源码知识,第二方面介绍JNI、ClassLoader、Java虚拟机、DVM&ART虚拟机和Hook等技术,第三方面介绍热修复原理、插件化原理、绘制优化和内存优化等与应用开发相关的知识点。3个方面有所关联并形成一个知识体系,从而使Android开发者能通过阅读本书达到融会贯通的目的。本书适合有一定基础的Android应用开发工程师、Android系统开发工程师和对Android系统源码感兴趣的读者阅读。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前沿技墅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Android 7.0的AMS家族
  • ActivityManager是一个和AMS相关联的类,它主要对运行中的Activity进行管理,这些管理工作并不是由ActivityManager来处理的,而是交由AMS来处理的。一般而言,ActivityManager 中的方法是会通过ActivityManagerNative(下面简称AMN)的getDefault方法来得到ActivityManagerProxy(下面简称 AMP ),通过 AMP 就可以和AMN进行通信,而AMN是一个抽象类,它将功能交由它的子类AMS来处理,因此,AMP就是AMS的代理类。AMS作为系统服务,很多API是不会暴露给ActivityManager的,因此ActivityManager并不算是AMS家族的一份子。为了讲解AMS家族,这里以Android 7.0的Activity启动过程来举例,在Activity的启动过程中会调用Instrumentation的execStartActivity方法,如下所示:
  • Android 8.0的AMS家族
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档