陌生知识点如下:
- 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 servicerawGetService(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); //真正的发送数据,写到驱动中。