理解ActivityManagerService

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

Android7.0的AMS家族

        ActivityManager是一个和AMS相关联的类,它主要对运行中的Activity进行管理,这些管理工作并不是由ActivityManager来处理的,而是交由AMS来处理的。ActivityManager中的方法会通过ActivityManagerNative (以后简称AMN)的getDefault方法来得到ActivityManagerProxy(以后简称AMP),通过AMP就可以和AMN进行通信,而AMN是一个抽象类,它将功能交由它的子类AMS来处理,因此,AMP就是AMS的代理类。AMS作为系统服务,很多API是不会暴露给ActivityManager的,因此ActivityManager并不算是AMS家族的一份子。

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

注释1处的descriptor值为android.app.IActivityManager,注释1处的代码主要用来查询本地进程是否有IActivityManager接口的实现,如果有则返回,如果没有就在注释2处将IBinder类型的AMS引用封装成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家族的主要部分

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

从图6-2可以看出,除ActivityManager外,在第5章介绍的ContextImpl如果想要和AMS进行通信也需要先经过AMP。

Android8.0的AMS家族

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

ActivityManager的getService方法,如下所示:

getService方法调用了IActivityManagerSingleton的get方法,IActivityManagerSingleton是一个Singleton类。在注释1处得到名为“activity”的Service引用(Context.ACTIVITY_SERVICE的值为“activity”),也就是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家族

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟、。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值