当前位置: 代码迷 >> 综合 >> Android binder 实例
  详细解决方案

Android binder 实例

热度:71   发布时间:2023-12-29 09:23:50.0

参考: 深入理解Binder

 

下面给出一个demo实例 

demo 下载链接

打印信息头文件

cur_log.h


#ifndef CUR_LOG_H
#define CUR_LOG_H#include <android/log.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>#ifdef __cplusplus
extern "C" {
#endif#undef  LOG_TAG
#define LOG_TAG "binder_test"#define cur_logi(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)  /* 普通打印信息 */
#define cur_loge(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) /* 错误打印信息 */
// #define cur_logi(fmt, args...)  printf("I %s " fmt "\n", LOG_TAG, ##args)
// #define cur_loge(fmt, args...)  printf("E %s " fmt "\n", LOG_TAG, ##args)
#define cur_enter() cur_logi("enter %s", __func__)
#define cur_exit()  cur_logi("exit %s", __func__)#ifdef __cplusplus
}
#endif/* CUR_LOG_H */
#endif

 

客户端 服务端 业务接口声明

IMyService.h

#ifndef IMYSERVICE_H
#define IMYSERVICE_H#include "cur_log.h"
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/String16.h>#define MY_SERVICE "coder.Myservice"using namespace android;
namespace android
{// 声明业务接口, Bp Bn 继承 业务接口class IMyService : public IInterface{public:// 定义命令字段enum{// SEND_INT = 0 , 可自定义SEND_INT = IBinder::FIRST_CALL_TRANSACTION,GET_STRING,GET_INT,SAY_HELLO,};// 使用宏,声明 MyService 业务接口,将业务和通信牢牢地钩在了一起DECLARE_META_INTERFACE(MyService);// 声明方法virtual void sendInt(int32_t val) = 0;virtual String8 getString() = 0;virtual int32_t getInt() = 0;virtual void sayHello() = 0;};// 声明客户端 BpMyServiceclass BpMyService : public BpInterface<IMyService>{public:BpMyService(const sp<IBinder>& impl);~BpMyService();virtual void sendInt(int32_t val);virtual String8 getString();virtual int32_t getInt();virtual void sayHello();};// 声明服务端 BnMyServiceclass BnMyService : public BnInterface<IMyService>{public:// BnXXService实现了onTransact函数,它将根据消息码调用对应的业务逻辑函数virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);BnMyService();~BnMyService();virtual void sendInt(int32_t val);virtual String8 getString();virtual int32_t getInt();virtual void sayHello();private:int32_t option;};}
#endif

 

客户端 服务端 实现

IMyService.cpp

#include "IMyService.h"
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>namespace android
{// 实现 IMPLEMENT_META_INTERFACE 宏模板定义 MyService 业务接口, 将业务和通信牢牢地钩在了一起IMPLEMENT_META_INTERFACE(MyService, MY_SERVICE);/****************************************************************************************************   客户端*/BpMyService::BpMyService(const sp<IBinder>& impl) : BpInterface<IMyService>(impl){}BpMyService::~BpMyService() {};void BpMyService::sendInt(int32_t val){Parcel data, reply;data.writeInterfaceToken(IMyService::getInterfaceDescriptor());data.writeInt32(val);remote()->transact(SEND_INT, data, &reply);}String8 BpMyService::getString(){Parcel data, reply;data.writeInterfaceToken(IMyService::getInterfaceDescriptor());remote()->transact(GET_STRING, data, &reply);String8 res = reply.readString8();return res;}int32_t BpMyService::getInt(){Parcel data, reply;data.writeInterfaceToken(IMyService::getInterfaceDescriptor());remote()->transact(GET_INT, data, &reply);int32_t val = reply.readInt32();return val;}void BpMyService::sayHello(){Parcel data, reply;data.writeInterfaceToken(IMyService::getInterfaceDescriptor());remote()->transact(SAY_HELLO, data, &reply);int32_t val = reply.readInt32();printf("say hello %d \n", val);}/****************************************************************************************************  服务端*/BnMyService::BnMyService(){option = 0;}BnMyService::~BnMyService(){}/* 接收远程消息,处理 onTransact 方法 */status_t BnMyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){switch(code){case SEND_INT:{CHECK_INTERFACE(IMyService, data, reply);int32_t val = data.readInt32();  // 调用服务类的函数sendInt(val);return NO_ERROR;}break;case GET_STRING:{CHECK_INTERFACE(IMyService, data, reply);String8 res = getString(); // 调用服务类的函数reply->writeString8(res);return NO_ERROR;}break;case GET_INT:{CHECK_INTERFACE(IMyService, data, reply);int32_t val = getInt(); // 调用服务类的函数reply->writeInt32(val);return NO_ERROR;}break;case SAY_HELLO:{CHECK_INTERFACE(IMyService, data, reply);sayHello();reply->writeInt32(2019);return NO_ERROR;}break;default:return BBinder::onTransact(code, data, reply, flags);}}void BnMyService::sendInt(int32_t val){option = val;}int32_t BnMyService::getInt(){return option;}String8 BnMyService::getString(){String8 str;if(option <= 0){str = String8("val <= 0");}else{str = String8("val > 0 ");}return str;}void BnMyService::sayHello(){printf("Hello, %s\n", __func__);}}

 

注册 service 到系统

MyService.cpp

#include "IMyService.h"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>int main(int argc __unused, char *argv[] __unused)
{sp < IServiceManager > sm = defaultServiceManager(); //获取service manager引用sm->addService(String16(MY_SERVICE), new BnMyService()); // 注册 MySerivce 服务到系统中// 开启线程池,接收处理Client发送的进程间通信请求ProcessState::self()->startThreadPool();  //启动线程池IPCThreadState::self()->joinThreadPool(); //把主线程加入线程池return 0;
}

客户端测试

MyService.cpp

#include "IMyService.h"
#include <binder/IServiceManager.h>int main()
{sp < IServiceManager > sm = defaultServiceManager(); //获取service manager引用sp < IBinder > binder = sm->getService(String16(MY_SERVICE));//获取名为 "coder.Myservice" 的binder接口if(binder == NULL){cur_loge("error, binder = NULL %s", __func__);return -1;}// 获取 client <--> servicesp<IMyService> service = IMyService::asInterface(binder);if(service == NULL){cur_loge("error, service = NULL %s", __func__);}for(int32_t i = 0; i < 10; i++){service->sendInt(-i);String8 str1 = service->getString();cur_logi("val = %d, str1 : %s", service->getInt(), str1.string());service->sendInt(i);String8 str2 = service->getString();cur_logi("val = %d, str2 : %s", service->getInt(), str2.string());}service->sayHello();return 0;
}

 

Android.mk

LOCAL_PATH := $(call my-dir)####################
# MyService
####################
include $(CLEAR_VARS)
#LOCAL_MODULE_TAGSS := optional
#LOCAL_MODULE_CLASS := minrray
LOCAL_SRC_FILES := IMyService.cpp \MyServer.cppLOCAL_C_INCLUDES += $(LOCAL_PATH) \$(TOP)/system/core/include/LOCAL_SHARED_LIBRARIES := libc libutils libcutils liblog libbinderLOCAL_MODULE := MyService
include $(BUILD_EXECUTABLE)####################
# Myclient
####################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := IMyService.cpp \MyClient.cppLOCAL_C_INCLUDES += $(LOCAL_PATH) \$(TOP)/system/core/include/LOCAL_SHARED_LIBRARIES := libc libutils libcutils liblog libbinderLOCAL_MODULE := MyClient
include $(BUILD_EXECUTABLE)

 

测试:

MyService &   # 运行服务
MyClient      # 运行测试

  相关解决方案