Android Binder实列篇
2015-10-16 19:21
615 查看
前言
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; }
点击下载源码
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories