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

一、示例

C层Binder开发的架构

binder代码路径:Android14\frameworks\native\libs\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

归纳一下,

 BBinder 实现了大部分的IBinder 接口,除了onTransact() 和 queryLocalInterface(), getInterfaceDescriptor();
 BnInterface 实现了IBinder的queryLocalInterface()和getInterfaceDescriptor(), 但是其必须借助实际的接口类。
 BnMediaPlayer只是定义了onTransact(), 没有实现。
 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() 函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值