binder在framework层,采用JNI技术来调用native(C/C++)层的binder架构,从而为上层应用程序提供服务。
还是直接从方法的注册和获取来解析。
Context中的addService方法首先必须获取ServiceManager代理,然后调用代理的addService方法。
ServiceManager的addService方法如下,
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
首先调用getIServiceManager获取对象,然后调用其addService方法。
getIServiceManager方法的调用流程图如下,
getIServiceManager获取的是什么对象呢?
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
首先看看BinderInternal的getContextObject返回的是什么对象,然后再看看asInterface方法。
getContextObject是native方法,
public static final native IBinder getContextObject();
对应的是android_util_Binder.cpp的android_os_BinderInternal_getContextObject,如下,
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
ProcessState的getContextObject方法获取的是BpBinder对象,相当于直接new BpBinder(0)。
javaObjectForIBinder方法根据BpBinder(C++)生成BinderProxy(Java)对象. 主要工作是创建BinderProxy对象,并把BpBinder对象地址保存到BinderProxy.mObject成员变量. 到此,可知
ServiceManagerNative.asInterface(BinderInternal.getContextObject())等价于
ServiceManagerNative.asInterface(new BinderProxy());
getContextObject返回的是BinderProxy(Java)对象。
ServiceManagerNative的asInterface方法如下,
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);//默认返回为null
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
因此,该方法相当于
new ServiceManagerProxy(new BinderProxy());
ServiceManagerProxy的构造方法如下,
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
因此mRemote变量指向BinderProxy对象。
private IBinder mRemote;
所以最终getIServiceManager方法返回的是ServiceManagerProxy对象。
1,native层, ServiceManager在客户端的代理对象是new BpServiceManager(new BpBinder(0));
2,在Java层, ServiceManager在客户端的代理对象是ServiceManager在客户端的代理对象是。