一个简单的例子:native service binder通信

本小结描述native层进程间binder通信,包括client端和 Server端. 下面将根据一个具体的事例来介绍如何在native层使用binder. 自顶往下看,首先看到的就是Android.mk, 可以看到在使用binder之前,依赖系统的动态库

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
       libcutils \
       libutils \
       libbinder
LOCAL_MODULE    := TestServer

LOCAL_SRC_FILES := \
      ITestService.cpp \
      TestServer.cpp

LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)

LOCAL_SHARED_LIBRARIES := \
      libcutils \
      libutils \
      libbinder

LOCAL_MODULE    := TestClient

LOCAL_SRC_FILES := \
      ITestService.cpp \
      TestClient.cpp
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

首先看一下测试例子得文件结构构成:

Test.h:定义interface的接口引用类,传输过程的枚举,client端的引用类.

ITestService.cpp: 实现引用类方法.

TestClient.cpp: 申明实现binder引用类.

TestServer.cpp: 申明实现binder实体类,往service manager里注册binder服务.

 

  • 申明service的接口ITestService(Test.h)
  • class ITestService : public IInterface
    {
        public:
            DECLARE_META_INTERFACE(TestService); // declare macro
            virtual void test()=0;
    };

    使用DECLARE_META_INTERFACE,主要做了一些函数的申明但并没有定义,主要的接口为:descriptor, asInterface, getInterfaceDescriptor接口。

  • 为ITestService接口的所有方法声明枚举,一个枚举对应ITestService里的一个方法(Test.h), 相当于ITestService里的test方法。
enum
{
    TEST = IBinder::FIRST_CALL_TRANSACTION,
};
  • 申明binder引用类BpTestService(Test.h), 这个类一般是在client端使用的。
class BpTestService: public BpInterface<ITestService> {
    public:
        BpTestService(const sp<IBinder>& impl);
        virtual void test();
};
  • 实现ITestService接口的方法(ITestService.cpp)

前面的DECLARE_META_INTERFACE,只是声明了接口的方法并没有实现,这里的代码实现了这些方法。

IMPLEMENT_META_INTERFACE(TestService, "android.TestServer.ITestService");

  • 实现binder引用类的BpTestService(TestClient.cpp)
#include "Test.h"
namespace android {
    BpTestService::BpTestService(const sp<IBinder>& impl) :
        BpInterface<ITestService>(impl) {
}
void BpTestService::test() {
    printf("in the get Test\n");
    Parcel data, reply;
    data.writeInterfaceToken(ITestService::getInterfaceDescriptor());
    remote()->transact(TEST, data, &reply);
    printf("send Print %d\n", reply.readInt32());
}
}

int main() {
    sp < IServiceManager > sm = defaultServiceManager();
    sp < IBinder > binder = sm->getService(String16("service.testservice"));
    sp<ITestService> cs = interface_cast < ITestService > (binder);
    cs->test();
    return 0;
}

Service client端通过service manager拿到binder的一个引用,也就是BpTestService. 它也会实现test方法,最终会通过跨进程调用binder实体对象BnInterface的test方法。在我们的实例中,只是要调用BpInterface的构造器,实现ITestService接口的test方法,client端实现test方法,通过 remote的transact 方法就能把数据交至server端,server的返回结果放在reply里。

  • 实现binder实体类的BnTestService(TestServer.cpp)

BnInterface是binder的核心库和框架中的类,表示binder的实体类,在onTransact中会根据client端传来的命令(正如上文的enum TEST)调用不用不同的函数。

#include "Test.h"

namespace android {
    class BnTestService: public BnInterface<ITestService> {
        public:
            virtual status_t;
            onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                uint32_t flags = 0);
            virtual void test() {
                printf("Now get test\n");
            }
    };
status_t BnTestService::onTransact(uint_t code, const Parcel& data,
        Parcel* reply, uint32_t flags) {
    switch (code) {
    case TEST: {
        printf("got the client msg\n");
        CHECK_INTERFACE(ITest, data, reply);
        test();
        reply->writeInt32(100);
        return NO_ERROR;
    }
    break;
   default:
       break;
   }
   return NO_ERROR;
}
}
int main() {
    sp < ProcessState > proc(ProcessState::self());
    sp < IServiceManager > sm = defaultServiceManager();
    sm->addService(String16("service.testservice"), new BnTestService());
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();  //等待线程结束
    return 0;
}
  • 结果验证

adb push TestService TestClient /system/bin

cd /system/bin

./TestService

./TestClient

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值