Android Binder实现示例(C/C++层)

本文参考前辈文章,记录自己学习了解Binder的一个过程;以一个例子来看下Binder的一个实现过程。

Java层的实现可参看另一篇文章:Android系统服务编写实例-Binder(Java层AIDL)

一、示例

C层Binder开发的架构图

BinderTest

├── client//客户端目录
│   ├── Android.mk
│   ├── BpBinderTest.cpp
│   ├── BpBinderTest.h
│   └── main_client.cpp
├── common//通用接口
│   ├── IBinderTest.cpp
│   └── IBinderTest.h
└── server//服务端目录
    ├── Android.mk
    ├── BinderTestService.cpp
    ├── BinderTestService.h
    ├── BnBinderTest.cpp
    ├── BnBinderTest.h
    └── main_server.cpp

1、common分析

1.1 IBinderTest.h

#ifndef ANDROID_IHELLOWORLDSERVICE_H
#define ANDROID_IHELLOWORLDSERVICE_H

#include <binder/IInterface.h>

namespace android{

enum {
    HW_HELLOWORLD2=IBinder::FIRST_CALL_TRANSACTION,
};

class IBinderTest: public IInterface//继承自IInterface,用于提供C/S的统一接口
{
public:
    DECLARE_META_INTERFACE(BinderTest);//这是一个宏定义
    virtual status_t binderTest(const char *str)=0;//一个简单的测试函数
};
    
};

#endif

1.2 IBinderTest.cpp

#include "IBinderTest.h"
#include "../client/BpBinderTest.h"
namespace android{
    IMPLEMENT_META_INTERFACE(BinderTest,"android.test.IBinderTest");//宏定义的实现(系统自动实现了)
};

2、Server分析

2.1 BnBinderTest.h

#include "../common/IBinderTest.h"

namespace android{

class BnBinderTest: public BnInterface<IBinderTest>//继承BnInterface
{
public:
    //onTransact此函数在BnBinderTest.cpp中具体实现,它用于处理来自client端对应的请求
    virtual status_t onTransact(uint32_t code,const Parcel &data,Parcel *reply,uint32_t flags =0);
};
};

2.2 BnBinderTest.cpp

#include <binder/Parcel.h>
#include "BnBinderTest.h"

namespace android {
//对BnBinderTest的onTransact实现,还会在后面其子类BnBinderTestService中重写此方法
status_t BnBinderTest::onTransact(uint32_t code,const Parcel &data,Parcel *reply,uint32_t flags)
{
    switch(code){
        case HW_HELLOWORLD2:{//在IBinderTest.h接口中定义
            CHECK_INTERFACE(IBinderTest,data,reply);//检查接口
            const char *str;
            str = data.readCString();
            reply->writeInt32(binderTest(str));//这里调用执行我们定义的binderTest函数
            return NO_ERROR;
        }break;
        default:
            return BBinder::onTransact(code,data,reply,flags);
    }
}
};

2.3 BinderTestService.h

#include<binder/Parcel.h>
#include"BnBinderTest.h"
#include<utils/Log.h>

namespace android {

class BinderTestService: public BnBinderTest//继承
{
public:
    static void instantiate();
    virtual status_t binderTest(const char *str);//实现接口IBinderTest的函数,这些是我们自己需要实现的一些功能函数
    virtual status_t onTransact(uint32_t code,const Parcel &data,Parcel *reply,uint32_t flags = 0);

private:
    BinderTestService();
    virtual ~BinderTestService();
};
};

2.4 BinderTestService.cpp

#include<binder/IServiceManager.h>
#include<binder/IPCThreadState.h>
#include<utils/Log.h>
#include"BinderTestService.h"

namespace android{
//这个函数是将自己注册进servicemanager
void BinderTestService::instantiate(){
    defaultServiceManager()->addService(String16("android.test.IBinderTest"),new BinderTestService);
}
//这个函数是我们要实现的功能,其在BnBinderTest的onTransact中被调用
status_t BinderTestService::binderTest(const char *str)
{
    ALOGI("receive string:%s\n",str);
    printf("print string:%s\n",str);//简单的打印一个字串
    return NO_ERROR;
}

BinderTestService::BinderTestService()
{
    ALOGI("BinderTestService is created");
    printf("BinderTestService is created\n");
}
BinderTestService::~BinderTestService()
{
    ALOGI("BinderTestService is destroyed");
    printf("BinderTestService is destroyed\n");
}

status_t BinderTestService::onTransact(uint32_t code,const Parcel &data,Parcel *reply,uint32_t flags)
{
    ALOGI("BinderTestService onTransact");
    printf("BinderTestService onTransact\n");
    return BnBinderTest::onTransact(code,data,reply,flags);//调用父类的函数
}
};

2.5 main_server.cpp(server端的启动程序)

#define LOG_TAG "main_server"

#include<binder/IPCThreadState.h>
#include<binder/ProcessState.h>
#include<binder/IServiceManager.h>
#include<utils/Log.h>
#include"BinderTestService.h"

using namespace android;

int main(int argc,char *argv[]){
    BinderTestService::instantiate();//注册进servicemanager中
    //开启线程池,接收处理Client发送的进程间通信请求
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    return 0;
}

 

2.6 Android.mk

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:=\
	../common/IBinderTest.cpp\
	BnBinderTest.cpp\
	BinderTestService.cpp\
	main_server.cpp

LOCAL_SHARED_LIBRARIES:=\
	libcutils\
	libutils\
	libbinder

LOCAL_MODULE:= main_server

include $(BUILD_EXECUTABLE)

3、Client分析

3.1 BpBinderTest.h

#include "../common/IBinderTest.h"

namespace android{

class BpBinderTest: public BpInterface<IBinderTest>
{
public:
    BpBinderTest(const sp<IBinder>& impl);
    virtual status_t binderTest(const char *str);
};
};

3.2 BpBinderTest.cpp

#include <binder/Parcel.h>
#include "BpBinderTest.h"
#include <utils/Log.h>

namespace android{

status_t BpBinderTest::binderTest(const char *str)
{
    Parcel data,reply;
    data.writeInterfaceToken(IBinderTest::getInterfaceDescriptor());
    data.writeCString(str);
    //通过code调用远程BinderTest方法,传递data
    status_t status = remote()->transact(HW_HELLOWORLD2,data,&reply);
    if(status != NO_ERROR){
        ALOGE("BinderTest error: %s",strerror(-status));
    }else{
        status = reply.readInt32();
    }
    return status;
}

BpBinderTest::BpBinderTest(const sp<IBinder>& impl): BpInterface<IBinderTest>(impl){}

};

3.3 main_client.cpp

#define LOG_TAG "main_helloworldclient"

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
#include "../common/IBinderTest.h"

using namespace android;

int main(int argc,char *argv[])
{
    ALOGI("HelloWorldSevice client is starting now");
    //获取ServiceManager,从而能得到远程IBinder,实现通信
    sp<IServiceManager> sm =defaultServiceManager();
    sp<IBinder> b;
    sp<IBinderTest> sBinderTest;

    do{
        b=sm->getService(String16("android.test.IBinderTest"));
        if(b != 0){
            break;
        }
        ALOGI("BinderTest is not working,waiting...");
        printf("BinderTest is not working,waiting...\n");
        usleep(500000);
    }while(true);
    sBinderTest = interface_cast<IBinderTest>(b);
    sBinderTest->binderTest("Hello,World!\n");
    return 0;
}

3.4 Android.mk

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:=\
	../common/IBinderTest.cpp\
	BpBinderTest.cpp\
	main_client.cpp

LOCAL_SHARED_LIBRARIES:=\
	libcutils\
	libutils\
	libbinder

LOCAL_MODULE:= main_client

include $(BUILD_EXECUTABLE)

DEMO下载:https://download.csdn.net/download/qq_25269161/10918706

 

如下参考

https://www.cnblogs.com/samchen2009/p/3316001.html

归纳一下,

  1.  BBinder 实现了大部分的IBinder 接口,除了onTransact() 和 queryLocalInterface(), getInterfaceDescriptor();
  2.  BnInterface 实现了IBinder的queryLocalInterface()和getInterfaceDescriptor(), 但是其必须借助实际的接口类。
  3.  BnMediaPlayer只是定义了onTransact(), 没有实现。
  4.  onTransact()的具体实现在Client类。

为什么搞得那么复杂?Google 是希望通过这些封装尽可能减少开发者的工作量,开发一个native的service 开发者只需要做这么几件事(上图中深色部分):

  1. 定义一个接口文件, IXXXService, 继承IInterface
  2. 定义BnXXX(), 继承 BnInterface<IXXXService>
  3. 实现一个XXXService类,继承BnXXX(), 并具体实现onTransact() 函数。

Client端的实现:

  1. 使用和Server端同一个 IXXXService, 继承IInterface
  2. 定义BpXXX(), 继承 BpInterface<IXXXService)
  3. 实现一个XXXService类,继承BpXXX(), 并具体实现transact() 函数。

 

Java层Binder的实现是采用了AIDL的方式。

Binder的Native和Java层对比
NativeJavaNote(Java侧说明)
IBinderIBinder 
IInterfaceIInterface 
IXXXIXXXAIDL文件接口定义
BBinderBinder通过JavaVBBinder类作为桥梁
BpBinderBinderProxy通过JNI访问Native的实现
BnInterfaceN/A 
BpInterfaceN/A 
BnXXXStubAIDL自动生成,需用户继承在子类中实现真正的服务端操作
BpXXXProxyAIDL自动生成,用于Client端调用

 

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇潇独行侠

如果有帮助到您,可以请杯快乐水

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值