Android binder 实例

参考: 深入理解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;

    };


// 声明客户端 BpMyService
    class 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();

    };


// 声明服务端 BnMyService
    class 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 <--> service
	sp<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.cpp

LOCAL_C_INCLUDES += $(LOCAL_PATH) \
					$(TOP)/system/core/include/

LOCAL_SHARED_LIBRARIES := libc libutils libcutils liblog libbinder

LOCAL_MODULE := MyService
include $(BUILD_EXECUTABLE)




####################
# Myclient
####################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := IMyService.cpp \
					 MyClient.cpp

LOCAL_C_INCLUDES += $(LOCAL_PATH) \
					$(TOP)/system/core/include/

LOCAL_SHARED_LIBRARIES := libc libutils libcutils liblog libbinder


LOCAL_MODULE := MyClient
include $(BUILD_EXECUTABLE)

 

测试:

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值