ServiceManger Binder的处理流程

陌生知识点如下:

  • 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); //真正的发送数据,写到驱动中。
                       
                        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值