题外话:由于同事咨询,口头讲解的话1对1,但不方便多方传播及继承性,因此特意写此文章讲解一番。1、androidservice简要说明:AndroidService:又称为JavaService,是实现在框架层里的Service,使用Java语言编写。NativeService:又称为SystemService,是实现在Runtime层里的Service。使用C++语言编写。对于这两种service来说,两个对等service通讯都是利用binder,只不过一种利用*.aidl,一种利用IInterface编写序列化代码而已,本质是一样的,本书先介绍nativeservice的编写及两个nativeservice如何通讯的过程:2、nativeservice的特点A、因为底层核心服务是Android框架里最接近Linux/Driver的部分。为了充分发挥硬件设备的差异化特性,核心服务是让上层Java应用程序来使用Driver/HWDevice特色的重要管道。B、在开机过程中,就可以启动核心服务(例如汉字输入法服务等),让众多应用程序来共享之。C、由于共享,所以能有效降低程序的大小及统一的接口变化。3、如何实现一个nativeservice要点如下:a、核心服务通常在独立的进程(Process)里执行。b、必须提供IBinder接口,让其它程序可以进行跨进程的绑定(Binding)和呼叫。c、因为共享,所以必须确保多线程安全(Thread-safe)。d、以C++类别定义,诞生其对象,透过SM之协助,将该对象参考值传给IServiceManager::addService()函数,就加入到BinderDriver里了。e、应用程序可透过SM之协助而远距绑定该核心服务,此时SM会回传IBinder接口给应用程序。f、应用程序可透过IBinder::transact()函数来与核心服务互传数据。下面以具体实例讲解一下具体的每个步骤如何实现完成先说明一个测试例子的模块结构:serviceTestA是一个普通的过程,提供两个整数的剩法及除法运算serviceTestB是一个普通的过程,提供两个整数的加法及减法运算TestService是一个测试进程的程序,主要验证两个服务进程的接口函数,其中的代码可以放在任何一个进程进行访问调用a、编写服务进程serviceTestA.h头文件定义:#ifndef__SERVICE_TEST_A__#define__SERVICE_TEST_A__#includeutils/RefBase.h#includebinder/IInterface.h#includebinder/Parcel.h#includeutils/threads.hnamespaceandroid{//继承BBinder类,从而提供IBinder接口classserviceTestA:publicBBinder{public:serviceTestA();virtual~serviceTestA();staticintinstantiate();//建立唯一类实例virtualstatus_tonTransact(uint32_t,constParcel&,Parcel*,uint32_t);private://protectedbymLock多线程安全mutableMutexmLock;};}#endif/*__SERVICE_TEST_A__*/serviceTestA.cpp实现文件:#includecutils/log.h#includecutils/properties.h#includebinder/IServiceManager.h#includebinder/IPCThreadState.h#includeserviceTestA/serviceTestA.hnamespaceandroid{enum{CALCULATE_MUL_NUM=0,CALCULATE_DIV_NUM,};intserviceTestA::instantiate(){LOGI(serviceTestAinstantiate);intr=defaultServiceManager()-addService(String16(service.TestA),newserviceTestA());LOGI(serviceTestAr=%d/n,r);returnr;}serviceTestA::serviceTestA(){LOGI(serviceTestAcreated);}serviceTestA::~serviceTestA(){LOGI(serviceTestAdestroyed);}status_tserviceTestA::onTransact(uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags){LOGI(serviceTestA::onTransactcode=%d,code);Mutex::Autolock_l(mLock);switch(code){caseCALCULATE_MUL_NUM:{inta=data.readInt32();intb=data.readInt32();intsum=a*b;LOGI(summulvalue=%d,sum);reply-writeInt32(sum);returnNO_ERROR;}break;caseCALCULATE_DIV_NUM:{inta=data.readInt32();intb=data.readInt32();intsum=a/b;LOGI(sumdivvalue=%d,sum);reply-writeInt32(sum);returnNO_ERROR;}break;default:returnBBinder::onTransact(code,data,reply,flags);}return0;}}Android.mk文件:LOCAL_PATH:=$(callmy-dir)include$(CLEAR_VARS)LOCAL_SRC_FILES:=serviceTestA.cppLOCAL_SHARED_LIBRARIES:=libutilslibutilslibbinderLOCAL_C_INCLUDES:=$(TOP)/frameworks/base/includeLOCAL_MODULE:=libServiceTestALOCAL_PRELINK_MODULE:=falseinclude$(BUILD_SHARED_LIBRARY)这里生成libServiceTestA动态库,方例升级服务程序编写独立的进程程序:它的用途是:诞生一个serviceTestA类别之对象,然后将该对象参考存入BinderDriver里。#includesys/types.h#includeunistd.h#includecutils/log.h#includebinder/IServiceManager.h#includebinder/IPCThreadState.h#includeserviceTestA/serviceTestA.husingnamespaceandroid;intmain(intargc,char*argv[]){spProcessStateproc(ProcessState::self());spIServiceManagersm=defaultServiceManager();LOGI(ServiceManager:%p,sm.get());serviceTestA::instantiate();//这是重点。。。。ProcessState::self()-startThreadPool();IPCThreadState::self()-joinThreadPool();return0;}Android.mk文件:LOCAL_PATH:=$(callmy-dir)include$(CLEAR_VARS)LOCAL_SRC_FILES:=main.cppLOCAL_SHARED_LIBRARIES:=libutilslibServiceTestALOCAL_MODULE:=serviceTestAinclude$(BUILD_EXECUTABLE)这里最重要的是调用:serviceTestA::instantiate();其先执行到newserviceTestA(),就诞生一个serviceTestA类别之对象;接着,呼叫defaultServiceManager()函数取得SM的IServiceManager接口;再呼叫IServiceManager::addService()将该对象参考存入BinderDriver里,并且同时存入到ServiceManager中注册并管理,如此其它进程才能通过ServiceManager::getService找到相应服务进程以上代码同理,serviceTestB服务进程也一样的这样建立,不再复述。b、测试服务进程testService.cpp编写:#includecutils/log.h#includecutils/properties.h#includebinder/IServiceManager.h#includebinder/IPCThreadState.h#includeserviceTestA/serviceTestA.h#includeserviceTestB/serviceTestB.husingnamespaceandroid;enum{CALCULATE_ADD_NUM=0,CALCULATE_SUB_NUM,};enum{CALCULATE_MUL_NUM=0,CALCULATE_DIV_NUM,};intmain(intargc,char*argv[]){spIBinderTestAbinder;spIBinderTestBbinder;Parceldata,reply;intsum=0;LOGI(testServicemainiscall...);spIServiceManagersm=defaultServiceManager();while(1){TestAbinder=sm-getService(String16(service.TestA));LOGE(TestA::getAddService%p/n,sm.get());if(TestAbinder==0){LOGE(TestAServicenotpublished,waiting...);usleep(1000000);continue;}else{LOGI(TestA::getAddServicesuccess...);break;}}while(1){TestBbinder=sm-getService(String16(service.TestB));LOGE(TestB::getAddService%p/n,sm.get());if(TestBbinder==0){LOGE(TestBServicenotpublished,waiting...);usleep(1000000);continue;}else{LOGI(TestB::getAddServicesuccess...);break;}}//测试两个service中的函数data.writeInt32(1000);data.writeInt32(200);LOGI(BpAddService::createremote()-transact()/n);TestAbinder-transact(CALCULATE_MUL_NUM,data,&reply);s