Binder机制,从Java到C (2. IPC in System Service :AMS)

1.建立Activity和Service的IPC之前

在上一篇 Binder机制,从Java到C (1. IPC in Application Remote Service)  里面有说到Activity通過AMS的bindService(),触发Service的onBind(),然后会调用Client的onServiceConnected() 回调方法,把一個Binder代理对象传递给Client。

那实际上,AMS也是一个Service,那它是运行在另外一個process,所以Activity要调用AMS.bindService()。来建立Application Activity和Service的IPC通信之前,首先得和AMS進行IPC通信。

我们在开发过程中,经常会创建一个Intent,然后start Activitystart Servicesend broadcast
如下面图中所示,所有Intent,都会通过IActivityManager走入Activity,Service,Broadcast三個不同的处理方法。这些处理都是在另外一个process进行的。就是AMS所在的进程。

Binder机制,从Java到C (2.  IPC in System Service :AMS)

2.AMS 框架

在AMS中,沒有使用aidl,而是自己去實現了Stub端和Proxy端。Stub端:ActivityManagerService,  Proxy 端:ActivityManagerProxy

下面这个图是以前分析AMS的时候一个框架图,拿来用一下,就看红框框的几个类吧。

ActivityManagerProxy就是提供给客户端的代理对象,客户端可以通过这个代理,请求AMS的服务。那这个请求当然是通过它里面的mRemote来发出的,这个mRemote当然也是BinderProxy啦。

ActivityManagerService继承了ActivityManagerNative,大部分AMS的功能执行都是在这里。

因为上面这两个类都实现了同一个接口文件IActivityManager,所以对客户端来说,通过代理来调用函数,就像调用远程服务一样。

Binder机制,从Java到C (2.  IPC in System Service :AMS)

3.Application获得AMS的Proxy

Application是怎麼得到AMS的Proxy的呢?这里就要从代码开始看起了。

3.1 就看startActivity好了,跟踪代码,最后会发现调用到ContexImpl中的:

/frameworks/base/core/java/android/app/ContextImpl.java

 public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
ActivityManagerNative.getDefault().startActivityAsUser(...);
}

代码很简单!但是这样就可以调用AMS的服务了。

3.2 那来看一下这个getDefault()究竟是什么:
/frameworks/base/core/java/android/app/ActivityManagerNative.java

    static public IActivityManager getDefault() {
return gDefault.get();
} private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity"); (1)
IActivityManager am = asInterface(b); (2)
return am;
}
};

 说明:

(1):原來也是获得了Activity service的IBinder,只是这个IBinder是从ServiceManager获得的。实际上和RemoteService的情況一樣,这个IBinder实际上也是一個BinderProxy对象。

(2) 返回的是ActivityManagerProxy,里面有個mRemote就是BinderProxy对象。

总结一下,上面这个过程可以概括的说是:
Application通过ServiceManager找到了AMS 的service代理对象,Application通過這個service代理对象也就可以和AMS通信了。

那接下來的问题就是:

servicemanager其实也是一個另外的进程,Application是怎么找到servicemanager的?或者说是怎么拿到servicemanager的BinderProxy的呢?

请看下一篇。

Binder机制,从Java到C (3. ServiceManager in Java)

上一篇:LeetCode: Palindrome 回文相关题目


下一篇:Docker(九)-Docker创建Selenium容器