返回

直击Binder机制的核心(下篇)(二)

Android

上篇中,我们已经了解了BinderInternal.getContextObject()这个native方法所做的两件事情:往ServerManager发送PING_TRANSACTION消息,和以0为地址创建BpBinder。接下来就是创建java层的ServiceManager代理了。

这部分代码位于system/core/java/android/os/ServiceManager.java中,关键代码如下:

public static IServiceManager getService() {
        synchronized (sServiceManagerLock) {
            if (sServiceManager != null) {
                return sServiceManager;
            }
            IBinder b = BinderInternal.getContextObject();
            sServiceManager = BpServiceManager.getService(b);
            return sServiceManager;
        }
    }

从这段代码可以看出,ServiceManager.getService()方法首先尝试从sServiceManager字段中获取ServiceManager代理,如果sServiceManager不为空,则直接返回。否则,调用BinderInternal.getContextObject()方法获取IBinder对象,然后调用BpServiceManager.getService()方法创建ServiceManager代理,并将其存储在sServiceManager字段中,最后返回ServiceManager代理。

BinderInternal.getContextObject()方法是一个native方法,其主要功能是往ServerManager发送PING_TRANSACTION消息,并以0为地址创建BpBinder。发送PING_TRANSACTION消息的目的是为了让ServerManager知道客户端的存在,以便ServerManager可以向客户端发送消息。创建BpBinder是为了给客户端提供一个Binder对象,以便客户端可以向ServerManager发送消息。

BpBinder是一个Binder代理类,它实现了IBinder接口,并提供了Binder对象的功能。BpBinder的构造函数如下:

public BpBinder(IBinder remote) {
    mRemote = remote;
}

在BpBinder的构造函数中,将IBinder对象remote作为参数传递进来,并将其存储在mRemote字段中。mRemote字段是BpBinder最重要的成员变量,它代表了BpBinder代理所绑定的远程Binder对象。

BinderInternal.getContextObject()方法的实现位于system/core/libcutils/binder.cpp文件中,关键代码如下:

sp<IBinder> getContextObject() {
    sp<IBinder> binder = defaultServiceManager()->getService(String16("servicemanager"));
    sp<IBinder> contextObject = binder->queryLocalInterface(String16("android.content.IContextManager"));
    if (contextObject != NULL) {
        return contextObject;
    }
    return binder;
}

在这段代码中,首先调用defaultServiceManager()->getService()方法获取servicemanager服务的IBinder对象,然后调用binder->queryLocalInterface()方法查询servicemanager服务是否实现了android.content.IContextManager接口。如果实现了,则返回IContextManager接口的IBinder对象,否则返回servicemanager服务的IBinder对象。

最后,BinderInternal.getContextObject()方法将获取到的IBinder对象返回。

至此,我们已经完成了对Binder机制核心的分析。