Android Binder实列篇

来源:互联网 发布:网络霸屏 编辑:程序博客网 时间:2024/06/07 05:24

前言

Binder是安卓应用最宽泛的进程间的通信方式,在分析安卓源码时少不了要和其打交道。对于一般开发人员而言只要知会其如何使用,如何实现进程间的通信即可,本文就是为了达到这个目的而写,一是给自己做一个备忘,二是让想了解binder通信的人员有个全局的认识。更深层次的研究请参考Android资料目录的Binder通信部分。
本文将通过实列的方式讲解如何实现binder通信,计划实现的列子框图如下:
这里写图片描述
SharedBufferService创建Ashmem并通过ServiceManager代理将自身加入系统服务。
ReadProcess/WriteProcess通过ServiceManager代理获取SharedBufferService代理,其后可以直接使用SharedBufferService提供的服务。

Service的实现

  • 服务接口ISharedBuffer的声明
#ifndef ISHAREDBUFFER_H_  #define ISHAREDBUFFER_H_  #include <utils/RefBase.h>  #include <binder/IInterface.h>  #include <binder/Parcel.h>  #include <binder/MemoryBase.h>#include <binder/MemoryHeapBase.h>#define SHARED_BUFFER "HidAudioSharedBuffer"  #define SHARED_BUFFER_SIZE (sizeof(CircleBuff_Cblk_t)+200*568)  using namespace android;  class ISharedBuffer: public IInterface  {  public:          DECLARE_META_INTERFACE(SharedBuffer);          //服务提供getBuffer()和setStatus(int status)接口        virtual sp<IMemory> getBuffer() = 0;          virtual void setStatus(int status)=0;};  class BnSharedBuffer: public BnInterface<ISharedBuffer>  {  public:          virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);  };  #endif 
  • ISharedBuffer.cpp的实现
#define LOG_TAG "SharedBuffer"#include <utils/Log.h>#include <binder/MemoryBase.h>#include "ISharedBuffer.h"using namespace android;enum{    GET_BUFFER = IBinder::FIRST_CALL_TRANSACTION,    SET_STATUS =IBinder::FIRST_CALL_TRANSACTION +1};class BpSharedBuffer: public BpInterface<ISharedBuffer>{public:    BpSharedBuffer(const sp<IBinder>& impl)        : BpInterface<ISharedBuffer>(impl)    {    }public:    sp<IMemory> getBuffer()    {    ALOGD("ISharedBuffer at %d   !\n",__LINE__);        Parcel data;        data.writeInterfaceToken(ISharedBuffer::getInterfaceDescriptor());        Parcel reply;        remote()->transact(GET_BUFFER, data, &reply);        sp<IMemory> buffer = interface_cast<IMemory>(reply.readStrongBinder());        return buffer;    }    void setStatus(int status){        //ALOGD("ISharedBuffer at %d status = %d !\n",__LINE__, status);        Parcel data;        data.writeInt32(status);        ALOGD("ISharedBuffer at %d status = %d !\n",__LINE__, status);        Parcel reply;        remote()->transact(SET_STATUS, data, &reply);    }};IMPLEMENT_META_INTERFACE(SharedBuffer, SHARED_BUFFER);status_t BnSharedBuffer::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    switch(code)    {    case GET_BUFFER:        {            ALOGD("ISharedBuffer at %d \n",__LINE__ );            //CHECK_INTERFACE(ISharedBuffer, data, reply);  //FIX ME ,have no right            sp<IMemory> buffer = getBuffer();            if(buffer != NULL)            {                reply->writeStrongBinder(buffer->asBinder());//匿名服务            }            return NO_ERROR;        }    case SET_STATUS:        {               ALOGD("ISharedBuffer at %d !\n",__LINE__ );            //CHECK_INTERFACE(ISharedBuffer, data, reply);  //FIX ME,have no right            ALOGD("ISharedBuffer at %d !\n",__LINE__ );            setStatus(data.readInt32());            return NO_ERROR;        }    default:        {            ALOGD("ISharedBuffer at %d status = %d !\n",__LINE__,data.readInt32() );            return BBinder::onTransact(code, data, reply, flags);        }    }}
  • 服务的实现
#define LOG_TAG "SharedBuffer"#include <utils/Log.h>#include <binder/MemoryBase.h>#include <binder/MemoryHeapBase.h>#include <binder/IServiceManager.h>#include <binder/IPCThreadState.h>#include <sys/types.h>#include <pthread.h>#include <media/IAudioPolicyService.h>#include <media/AudioSystem.h>#include <system/audio.h>#include "stdio.h"#include "ISharedBuffer.h"#include "circleBuffer.h"int connected=0;class SharedBufferService : public BnSharedBuffer{public:    SharedBufferService(){        CircleBuff_Cblk_t cblk;        sp<MemoryHeapBase> heap = new MemoryHeapBase(SHARED_BUFFER_SIZE, 0, "SharedBuffer");//创建ashmem        if(heap != NULL){            mMemory = new MemoryBase(heap, 0, SHARED_BUFFER_SIZE);            char * data = (char *)mMemory->pointer();            Mutex lock(Mutex::SHARED,"hidAudioBuffMutex");            if(data !=NULL){                cblk.freeSize = SHARED_BUFFER_SIZE -sizeof(cblk);                //cblk.buffLock =new Mutex(Mutex::SHARED,"hidAudioBuffMutex");                memcpy(&(cblk.buffLock),&lock,sizeof(lock));                cblk.writeIndex=0;                cblk.readIndex =0;                cblk.empty=1;                cblk.full =0;                cblk.offset =sizeof(cblk);                cblk.dataAvailed =0;                cblk.size   = SHARED_BUFFER_SIZE - cblk.offset;                memcpy(data ,&cblk, sizeof(cblk));            }        }    }    virtual ~SharedBufferService()    {        mMemory = NULL;    }public:    static void instantiate()    {        defaultServiceManager()->addService(String16(SHARED_BUFFER), new SharedBufferService());//通过instantiate()将服务添加到系统服务    }    //实现ISharedBuffer定义的服务接口    virtual sp<IMemory> getBuffer()    {    ALOGD("MonitorHidThread %d !\n",__LINE__ );        return mMemory;    }    virtual void setStatus(int status){        ALOGD("MonitorHidThread %d !\n",__LINE__ );        connected =status;    }private:    sp<MemoryBase> mMemory;};int main(int argc, char** argv){    SharedBufferService::instantiate();//添加服务到系统    ProcessState::self()->startThreadPool();//实际和IPCThreadState::self()->joinThreadPool()效果一样    IPCThreadState::self()->joinThreadPool();//创建线程与binder内核驱动交互    //为什么要创建两个线程?人多力量大??    return 0;}

客户端的实现

#define LOG_TAG "SharedBufferClient"#include <utils/Log.h>#include <binder/MemoryBase.h>#include <binder/IServiceManager.h>#include "../ISharedBuffer.h"#include "../circleBuffer.h"#include   <unistd.h>int main(){        sp<IBinder> binder = defaultServiceManager()->getService(String16(SHARED_BUFFER));//通过binder管理代理获取SHARED_BUFFER服务bpBinder        if(binder == NULL)        {                printf("Failed to get service: %s.\n", SHARED_BUFFER);                return -1;        }        sp<ISharedBuffer> service = interface_cast<ISharedBuffer>(binder);//创建SHARED_BUFFER服务代理对象        if(service == NULL)        {                return -2;        }        sp<IMemory> buffer = service->getBuffer();//获取服务提供的Ashmem        if(buffer == NULL)        {                return -3;        }        CircleBuff_Cblk_t *cblk = (CircleBuff_Cblk_t *)buffer->pointer();        if(cblk == NULL)        {            printf("get the cblk failed!");            return -4;        }        printf("size =%d wIndex =%d rIndex=%d empty=%d full=%d dataAvai=%d free =%d\n",cblk->size \             ,cblk->writeIndex,cblk->readIndex,cblk->empty,cblk->full,cblk->dataAvailed,cblk->freeSize);        int i =0;        char buf[256];        memset(buf,0,sizeof(buf));        for(i=0; i<256 ;i++){            buf[i]=i;        }        int n=0 ,writed=0;        while(1){                writed = WriteData(cblk,buf+n,20);                if(writed !=20){                    printf("error : write data != 20 !!! please check!\n");                }                printf("size =%d wIndex =%d rIndex=%d empty=%d full=%d dataAvai=%d free =%d\n",cblk->size \                     ,cblk->writeIndex,cblk->readIndex,cblk->empty,cblk->full,cblk->dataAvailed,cblk->freeSize);                n+=20;                if(n>235)                    n=0;                sleep(1);        }        return 0;}

点击下载源码

0 0
原创粉丝点击