上一篇,了解了一下Binder通信机制的基本框架。此篇将用一个示例来说明一个。非常感谢一位网上朋友的源码分享,博主还有更多精彩Android框架分析文章。

添加Test模块服务,方法姑且定义一个为test。


(1)程序构成

编译binder程序需要链接binder动态链接库,应用开发环境下使用ndk编程是不能链接binder动态链接库的,故此需要在源码开发环境下。本实例在vendor目录下建立了子目录shuame,然后把工程目录放在该目录下。

程序由2个部分组成,一个binder service程序,一个测试binder service的client程序,对应的Android.mk如下所示:

LOCAL_PATH := $(call my-dir) #生成binder service的服务端include $(CLEAR_VARS)LOCAL_SHARED_LIBRARIES := \    libcutils \    libutils \    libbinder       LOCAL_MODULE    := TestServerLOCAL_SRC_FILES := \    ITestService.cpp \    TestServer.cpp   LOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE)  #生成binder service的测试client端include $(CLEAR_VARS)LOCAL_SHARED_LIBRARIES := \    libcutils \    libutils \    libbinderLOCAL_MODULE    := TestClientLOCAL_SRC_FILES := \    ITestService.cpp \    TestClient.cppLOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE)

(2)程序源代码构成

Test.h :包含需要用到的头文件,声明接口,定义操作枚举,声明binder引用类

ITestService.cpp: 接口类方法的实现

TestServer.cpp: 声明并实现binder实体类 ,启动binder服务,并在service manager里注册

TestClient.cpp: 声明并实现binder 引用类, 测试binder服务的client


1. 声明Service的接口ITestService(test.h)

// Binder Service 接口test声明    class ITestService : public IInterface    {    public:        DECLARE_META_INTERFACE(TestService); // declare macro        virtual void test()=0;    };// 客户端服务端通讯使用    enum    {        TEST = IBinder::FIRST_CALL_TRANSACTION,    };
2.完成BpTestService的声明,test实现

声明:

// BpXXX继承IXXX,完成test接口的实现,通过remote()->transact()远程调用到BnXXX::onTransaction(){ cast TEST: xxxx;}    class BpTestService: public BpInterface<ITestService> {    public:    BpTestService(const sp<IBinder>& impl);    virtual void test();    };
实现:

IMPLEMENT_META_INTERFACE(TestService, "android.TestServer.ITestService");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());}

3. 完成BnTestService接口类的声明,实现

声明:

class BnTestService: public BnInterface<ITestService> {public:virtual status_tonTransact(uint32_t code, const Parcel& data, Parcel* reply,uint32_t flags = 0);virtual void test() {printf("Now get test\n");}};

实现onTransact()方法:

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;}
4. 实现客户端Client

 int main() {    /*获取service manager引用*/sp<IServiceManager> sm = defaultServiceManager();/*获取test service的binder接口对象*/sp<IBinder> binder = sm->getService(String16("service.testservice"));/*转为sp<ITestService>*/sp<ITestService> cs = interface_cast<ITestService>(binder);/*通过binder引用调用test方法*/    cs->test();    return 0;}
5.实现Server端

 int main() {    ProcessState::self();  //初始化单例    /*获取service manager的binder引用*/    sp<IServiceManager> sm = defaultServiceManager();     /*添加服务 注意字符串必须用String16类型*/    sm->addService(String16("service.testservice"), new BnTestService());    ProcessState::self()->startThreadPool(); //启动线程池    IPCThreadState::self()->joinThreadPool();//等待线程结束    return 0;}
6.编译生成TestServer,TestClient,分别push到Andrlid设备中,修改权限,运行并测试

架构和Android上的多媒体播放框架有点不一样,完成播放接口能力放在了Client的类中,而整个多媒体服务MediaPlayerService则负责创建并管理这些Client客户端。

总之,XXXXX是继承BnXXXX,BnXXXX继承IXXXX,BnXXXX中继承IXXXX中的虚函数必须被实现后才能被实例化,通常是在XXXX中被实现,主要XXXX就可以被实例化。


更多相关文章

  1. 【Android(安卓)Training - 03】使用Fragments建立动态的UI [ Le
  2. Android应用程序窗口(Activity)实现框架简要介绍和学习计划
  3. 在Android上使用OpenCL调用GPU加速
  4. Android远程接口之AIDL——Parcelable、in、out、inout简例
  5. Android(安卓)5.0之后隐式声明Intent 启动Service引发的问题
  6. Android应用启动过程浅析
  7. android 的AIDL学习
  8. Android(安卓)蓝牙(概述)
  9. 7、与iOS、Android的交互 高级篇

随机推荐

  1. 为什么经过三十年的发展,现代计算机的响应
  2. 互联网协议的演变之路
  3. 阿里自研分布式强一致关系型数据库——X-
  4. 所有人都在渲染程序员的中年危机,我们却在
  5. 中国第一份 DevOps 年度调查报告重磅发布
  6. 理性思维VS中二晚期,二次元程序员调查报告
  7. 技术管理从0到1,并没有你想象的那么难!
  8. 当别人用月薪去衡量程序员时,我们自己应该
  9. 假如程序员会武功?
  10. 虽然难用,但12306面临的业务场景复杂度可