概述
在上一节Binder 通信笔记(native)中,分析了在c++层service和client是怎样与binder驱动通信的。在Android中,绝大部分的应用和很多关键的系统Service是用Java来完成的。这一节,我们分析一下Java层程序是如何使用binder驱动进行通信的。其实Java层的binder通信是基于native的,它只是把binder的“网络层”(BpBinder和BBinder)做了一下封装,通过JNI将业务发送给了上一层。先看以下结构图
可以看到native层的类关系图和上一节下半部分完全相同,java层多了BinderProxy.class和Binder.class将native层的数据传送到上层。这一节我们只分析上半部分代码,下半部分的代码请查看上一节Binder 通信笔记(native)。
Service注册
这一节以ActivityManagerService为例,分析以下Java层Service注册到serviceManager的过程。ActivityManagerService是在SystemServer进程里面注册的,本节以分析binder为主,SystemServer的启动过程这里就不说了,网上有很多资料。大概流程是
SystemServer:main()
->run()
->startBootstrapServices()
->mActivityManagerService.setSystemProcess();
->ServiceManager.addService("activity", this, true);
下面看一下ServiceManager.addService的实现。
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
获取service_manager代理
在Java层有一个ServiceManager.class作为service_manager的代理,它是如何实现的呢,我们继续跟代码,看一下getIServiceManager()
。
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
ServiceManager是一个单例实现,第一次初始化执行了ServiceManagerNative.asInterface(BinderInternal.getContextObject())
。先看一下括号里吗的参数。BinderInternal.getContextObject()
是一个native函数。它的实现在android_util_Binder.cpp里面
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
ProcessState::self()->getContextObject(NULL);
上一篇博客已经分析过,它返回了BpBinder(0), 这个0就代表着远程为service_manager。继续看一下javaObjectForIBinder();
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
//1
if (val->checkSubclass(&gBinderOffsets)) {
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
AutoMutex _l(mProxyLock);
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
// 2
if (object != NULL) {
jobject res = jniGetReferent(env, object);
if (res != NULL) {
ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
return res;
}
LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
//3
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
// The proxy holds a reference to the native object.
env->