陌生知识点如下:
- BinderProxy:是将Native层的BpBinder对象进行封装后传给Java层使用的Binder对象
- android_util_binder: Binder在JNI层的相关注册,处理,转换封装接口
- BpBinder:Binder驱动在Native层的封装。
- IPCThreadState:线程池对象
- ServiceManager: 就像互联网的DNS服务器(地址为0)
以APP调用ServiceManager为例进行分析,分析ServiceManger Binder的处理流程:
SM内存放着许多<string, Binder>的数组,可以通过getService(String name)获取到对应用Binder,这是键值对。
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
-->ServiceManager.java->getService():
-->IBinder service = sCache.get(name)
return service
rawGetService(name);
-->final IBinder binder = getIServiceManager().getService(name);
-->getIServiceManager()实现: //IServiceManager.aidl接口文件用于跨进程通信
-->sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()))
-->asInterface(Ibinder obj):
-->return new ServiceManagerProxy(obj); //返回一个Proxy的Binder对象。
--》ServiceManagerProxy是一个类: class ServiceManagerProxy Implements IServiceManager{
在它的构造函数中:
public ServiceManagerProxy(IBinder remote){
mRemote = remote;
mServiceManager = IServiceManager.Stub.asInterface(remote); //转成Proxy对象
}
}
//分析下面这个接口:这个是获取ServiceManager的IBinder,与其它Server的不同。
-->BinderInternal.getContextObject():
这个getContextObject接口的定义为:static final native IBinder getContextObject();//请进入Native看代码,返回的是BinderProxy对象(下面有说明)
-->android_util_Binder.cpp->gBinderInternalMethods[]={
{"getContextObject", "...", android_os_BinderInternal_getContextObject}; //映射到右边的Native接口
...
}
android_os_BinderInternal_getContextObject: //返回的是BinderProxy对象。(下面有说明)
-->sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
-->ProcessState:就是一个进程,每个进程启动时就会启动一个ProcessState.
//位于ProcessState.cpp中:Zygote Fork()一个进程时就会创建ProcessState,
//或者也可以这么理解,ProcessState就是进程在Native层的一个表示
//主要管理Binder驱动的初始化,管理Binder交互的线程池等操作
//Native层的getContextObject主要目的是为了构建获取Native层的IBinder对象(BPBinder)。
//所有进程获取的IBinder对象在Native层都由它获取,Binder创建也由ProcessState创建。
sp<IBinder> context = getStrongProxyForHandle(0);
//上面这个语句参数0:要特别注意,0就像固定的IP地址,指的就是ServiceManage服务。
//SM是ServiceManager<name, binder>中的第0个对象,因为SM也是一个进程,它就像互联网中的DNS服务器,
//DNS服务器的地址是公开的,所以这边SM的handle为0,是固定的,是列表中的第0号Binder对象。
-->b = BpBinder::create(handle) //这个handle = 0; //创建SM的BpBinder并保存下来,方便后面再查找。
result = b;
return result;
//BpBinder是给java使用的,所以要封装成java能识别的数据结构。
//需要进行数据的转换与处理:这些是JNI的知识点
//下面接口返回的是基于BpBinder对像封装出来的BinderProxy对象(JAVA用)
return javaObjectForIBInder(env,b); //b就是SM在Native的BPBinder.//返回的是jobject对象,是反射参数的java的BinderProxy
//使用到Java中的反射:运行了BinderProxy.java中的getInstance()方法
--> jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
-->BinderProxy.java中的getInstance()方法:
-->result = new BinderProxy(nativeData); //构建了BinderProxy对象,这个是Java层的Binder代理
return binder;
通过前面的代码分析,可以得到一个结论,ServiceManager的Binder封装过程如下图所示:其它所有服务端提供的Service的Binder的封装逻辑也是相同的逻辑,举一反三。
下面再以更加简洁的流程描述上这整个获取ServiceManager过程的调用逻辑:
ServiceManagerProxy(它是一个Stub.Proxy对象)-》 IServiceManager.Stub.Proxy.getService():
-->mRemote.transact();
-->BinderProxy.cpp->transact(); //从ServiceManagerProxy->到BinderProxy,这一层是framework层
-->transactNative();
-->进入android_util_binder.cpp->android_os_BinderProxy_transact(); //这一层是JNI层
-->数据类型转换,因为 下面要传给Native层
parcelForJavaObject();
IBinder* target=getBPNativeData();
target->transact(); //target就是BpBinder ,这个接口调用进入BpBinder.cpp,进入Native层
-->IPCTrheadState.cpp:IPCThreadState::self()->transact(); //安排一个线程去处理binder的通信传输
-->writeTransactionData(); //准备数据
-->将数据写入结构体中,这里省略。
mOut.write(cmd);
mOut.write(&tr, sizeof(tr)); //只是将数据放到mOut这个Parcel对象中,但还未发送
-->waitForResponse(); //这里是真正的发送数据的过程 。
-->talkWithDriver();
-->bwr.write_buffer = mOut.data() ; //取出out中的数据放到bwr中
ioctl(FD, BINDER_WRITE_READ, &bwr); //真正的发送数据,写到驱动中。