Android(安卓)Binder通信机制学习(二)
上一篇,了解了一下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就可以被实例化。
更多相关文章
- 【Android(安卓)Training - 03】使用Fragments建立动态的UI [ Le
- Android应用程序窗口(Activity)实现框架简要介绍和学习计划
- 在Android上使用OpenCL调用GPU加速
- Android远程接口之AIDL——Parcelable、in、out、inout简例
- Android(安卓)5.0之后隐式声明Intent 启动Service引发的问题
- Android应用启动过程浅析
- android 的AIDL学习
- Android(安卓)蓝牙(概述)
- 7、与iOS、Android的交互 高级篇