前面的一篇文章《android—binder进程间通讯流程分析》 分析过,service一般都是需要先去service manager注册后,然后才能去使用。而匿名binder就是没有去service manager注册的service,既然没去注册,那么内核中就没有相应的binder_node和binder_ref结构,那么如何使用?下面以BufferQueuemGraphicBufferAlloc对象产生为例。

BufferQueue::BufferQueue(const sp<IGraphicBufferAlloc>& allocator) :    mDefaultWidth(1),    mDefaultHeight(1),    mMaxAcquiredBufferCount(1),    mDefaultMaxBufferCount(2),    mOverrideMaxBufferCount(0),    mConsumerControlledByApp(false),    mDequeueBufferCannotBlock(false),    mUseAsyncBuffer(true),    mConnectedApi(NO_CONNECTED_API),    mAbandoned(false),    mFrameCounter(0),    mBufferHasBeenQueued(false),    mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),    mConsumerUsageBits(0),    mTransformHint(0){    // Choose a name using the PID and a process-unique ID.    mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());    ST_LOGV("BufferQueue");    if (allocator == NULL) {        //①获取BpSurfaceComposer        sp<ISurfaceComposer> composer(ComposerService::getComposerService());        //②获取mGraphicBufferAlloc        mGraphicBufferAlloc = composer->createGraphicBufferAlloc();        if (mGraphicBufferAlloc == 0) {            ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");        }    } else {        mGraphicBufferAlloc = allocator;    }}

上面BufferQueue的构造函数中,
首先在①中获取了BpSurfaceComposer,前面有介绍,不展开;
②是获取mGraphicBufferAlloc ,下面详细分析。

sp<IGraphicBufferAlloc> mGraphicBufferAlloc;

从定义看,mGraphicBufferAlloc应该是GraphicBufferAlloc服务的代理对象,但是GraphicBufferAlloc并没有去service manager去注册。

下面看BpSurfaceComposercreateGraphicBufferAlloc()函数。

    virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc()    {        uint32_t n;        Parcel data, reply;        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());        remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, data, &reply);        //从reply中,即内核的返回值中readStrongBinder        return interface_cast<IGraphicBufferAlloc>(reply.readStrongBinder());    }

主要的代码就是interface_cast(reply.readStrongBinder());,从reply.readStrongBinder()中返回BpBinder(handle),然后通过interface_cast转换为BpGraphicBufferAlloc对象。
那么这个binder对象是如何从server,即surface flinger中传过来的?下面看server端代码,

status_t BnSurfaceComposer::onTransact(    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){        case CREATE_GRAPHIC_BUFFER_ALLOC: {            CHECK_INTERFACE(ISurfaceComposer, data, reply);            //调用surface flinger的createGraphicBufferAlloc函数            //GraphicBufferAlloc类继承自BnInterface            sp<IBinder> b = createGraphicBufferAlloc()->asBinder();            //将binder实体写入            reply->writeStrongBinder(b);            return NO_ERROR;        }}
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc(){    //真实的服务是GraphicBufferAlloc    //class GraphicBufferAlloc : public BnGraphicBufferAlloc    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());    return gba;}

GraphicBufferAlloc类继承自BnInterface,这里调用BnInterfaceonAsBinder(),所以返回的就是GraphicBufferAlloc new出来的指针。

template<typename INTERFACE>IBinder* BnInterface::onAsBinder(){    return this;}

调用reply->writeStrongBinder(b);,将GraphicBufferAlloc对象传入内核,这个在前面文章已经介绍过,当将binder实体GraphicBufferAlloc对象传入内核后,内核会为实体所对应的进程的binder_proc,也就是surface flinger,中创建一个实体对应的binder_node,然后在目标进程,也就是BufferQueue所在的进程中创建一个binder_ref指向前面的binder_node,然后返回给BufferQueue所在的进程一个handle,这个就打通了binder的传递流程。
从上面的分析,得到以下结论:
① service不是必须去service manager中注册后才能去使用;
② 匿名binder必须是建立在一个实名binder之上的,实名binder就是在service manager中注册过的。首先client和server通过实名binder建立联系,然后把匿名binder通过这个实名通道“传递过去”,对方也可以正确获取service的代理对象Bpxxx;
③ 为何需要匿名binder?对于android graphic系统来说,一个Layer对应一个BufferQueue,所以一个应用程序可能会有多个BufferQueue。当BufferQueue构造时,会去surface flinger进程中去创建一个new GraphicBufferAlloc(),所以一个应用程序会在surface flinger进程中创建多个GraphicBufferAlloc对象,我认为匿名Binder一般都是在这种情景中出现的,service有多个实体,在需要使用时,现场创建Binder实体。而一般实名Binder,即是去service manager中注册的service,都只会有一个service实体,即只会new一次。

更多相关文章

  1. Android(安卓)Material Design Snackbar Example
  2. Android(安卓)TextView当中设置超链接、颜色、字体
  3. Android(安卓)XML小工具
  4. android persistent属性研究
  5. android开发两种退出程序方式(killProcess,System.exit)
  6. ActivityManagerService启动流程详解
  7. Android消息机制(Handler、Looper、MessageQueue)
  8. Android的Application对象讲解
  9. 阿里架构师最新整理 Android(安卓)面试点梳理,你收藏了吗?

随机推荐

  1. android复制数据库到SD卡
  2. Android(安卓)主线程子线程执行关系
  3. Android(安卓)Studio修改默认Activity继
  4. Android(安卓)技术提升总结(持续更新)
  5. Android页面跳转错误解决
  6. Android热插拔事件处理流程--Vold
  7. Android相关知识
  8. 剪切图片-扩展android 选择图片(从手机照
  9. Android中使用Tcpdump抓取网络数据包
  10. Android(安卓)Studio - 第四十七期 毛玻