C++使用binder实例
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C++使⽤binder实例
Android系统最常见也是初学者最难搞明⽩的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。
所以搞明⽩Binder的话,在很⼤程度上就能理解程序运⾏的流程。
这是⼀个⽤C++写的binder,⼀个服务器⼀恶搞客户端,代码如下:
server.cpp
1 #include <binder/IServiceManager.h>
2 #include <binder/IBinder.h>
3 #include <binder/Parcel.h>
4 #include <binder/ProcessState.h>
5 #include <binder/IPCThreadState.h>
6 #include <android/log.h>
7using namespace android;
8 #ifdef LOG_TAG
9#undef LOG_TAG
10#endif
11#define LOG_TAG "testService"
12
13#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "ProjectName", __VA_ARGS__)
14#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "ProjectName", __VA_ARGS__)
15#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , "ProjectName", __VA_ARGS__)
16#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , "ProjectName", __VA_ARGS__)
17#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "ProjectName", __VA_ARGS__)
18
19class MyService : public BBinder
20 {
21public:
22 MyService()
23 {
24 mydescriptor = String16("media.hello");
25 n=0;
26 }
27virtual ~MyService() {}
28//This function is used when call Parcel::checkInterface(IBinder*)
29virtual const String16& getInterfaceDescriptor() const
30 {
31 LOGE("this is enter ==========getInterfaceDescriptor");
32return mydescriptor;
33 }
34protected:
35void show()
36 {
37 LOGE("this is for test show");
38 LOGE("this is for test show");
39 LOGE("this is for test show");
40 LOGE("this is for test show");
41 LOGE("this is for test show");
42 }
43virtual status_t onTransact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags = 0)
44 {
45 LOGD("enter MyService onTransact and the code is %d",code);
46/*
47 if (data.checkInterface(this))
48 LOGD("checkInterface OK");
49 else
50 {
51 LOGW("checkInterface failed");
52 return BBinder::onTransact(code, data, reply, flags);
53 }
54*/
55switch (code)
56 {
57case1:
58 LOGD("MyService interface 1");
59break;
60case2:
61 LOGD("MyService interface 2");
62 cb = data.readStrongBinder();
63break;
64case3:
65 {
66 LOGD("MyService interface 3, exit");
67//No unregister service routine?
68//It should return to client first and then call exit in another place.
69 exit(0);
70break;
71 }
72case4:
73 {//call cb
74 LOGD("MyService interface 4 before if================");
75 cb = data.readStrongBinder();
76if (cb != NULL)
77 {
78 LOGD("MyService interface 4");
79 Parcel in, out;
80in.writeInterfaceToken(String16("android.os.ISetupCallback"));
81in.writeInt32(n++); //向客户端发送数据
82
83in.writeCString("This is a string !");
84 cb->transact(2, in, &out, 0);
85 show();
86 }
87break;
88 }
89default:
90return BBinder::onTransact(code, data, reply, flags);
91 }
92return0;
93 }
94private:
95 String16 mydescriptor;
96 sp<IBinder> cb;
97int n;
98 };
99int main()
100 {
101 sp<IServiceManager> sm = defaultServiceManager(); //获取ServiceManager服务代理
102 status_t ret;
103//register MyService to ServiceManager
104 MyService* srv = new MyService();
105 ret = sm->addService(String16("media.hello"), srv); // 注册服务
106 LOGD("addservice media.hello return %d", ret);
107//call binder thread pool to start
108 ProcessState::self()->startThreadPool();
109 IPCThreadState::self()->joinThreadPool(true); //参数默认也是true,进⼊服务的循环监听状态
110return0;
111 }
clinet.cpp
1 #include <binder/IServiceManager.h>
2 #include <binder/IBinder.h>
3 #include <binder/Parcel.h>
4 #include <binder/ProcessState.h>
5 #include <binder/IPCThreadState.h>
6 #include <private/binder/binder_module.h>
7 #include <android/log.h>
8
9using namespace android;
10 #ifdef LOG_TAG
11#undef LOG_TAG
12#endif
13#define LOG_TAG "testCallback"
14
15#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "ProjectName", __VA_ARGS__)
16#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "ProjectName", __VA_ARGS__)
17#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , "ProjectName", __VA_ARGS__)
18#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , "ProjectName", __VA_ARGS__)
19#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "ProjectName", __VA_ARGS__)
20
21class MySetupCallback : public BBinder
22 {
23public:
24 MySetupCallback()
25 {
26 mydescriptor = String16("android.os.ISetupCallback");
27 }
28virtual ~MySetupCallback() {}
29virtual const String16& getInterfaceDescriptor() const
30 {
31return mydescriptor;
32 }
33protected:
34virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
35 {
36 LOGD("enter MySetupCallback onTransact, code=%u", code);
37if (data.checkInterface(this)) //检查 mydescriptor 类描述字符串
38 LOGD("checkInterface OK");
39else
40 {
41 LOGW("checkInterface failed");
42return -1;
43 }
44switch (code) //code为服务器发送的code,根据code实现不同的函数
45 {
46case1:
47 LOGD("From Server code = %u", code);
48 LOGD("From Server code = %u", code);
49break;
50case2:
51 {
52 LOGD("From Server code = %u", code);
53 LOGD("Frome server data = %d", data.readInt32()); //从服务端接收数据
54 LOGD("Frome server string = %s", data.readCString());
55
56break;
57 }
58default:
59break;
60 }
61return0;
62 }
63private:
64 String16 mydescriptor;
65 };
66
67int main()
68 {
69 sp<IServiceManager> sm = defaultServiceManager(); //获取ServiceManager服务代理
70 sp<IBinder> b = sm->getService(String16("media.hello")); //查询服务
71if (b == NULL)
72 {
73 LOGW("Can't find binder service \"media.hello\"");
74return -1;
75 }
76 Parcel in1,out1;
77 MySetupCallback *cb = new MySetupCallback();
78 in1.writeStrongBinder(sp<IBinder>(cb));
79int ret = b->transact(4, in1, &out1, 0); //TRANSACTION_registerSetup = 4
80 LOGD("transact(4) return %d", ret);
81 ProcessState::self()->startThreadPool();
82 IPCThreadState::self()->joinThreadPool(); //参数默认也是true,进⼊服务的循环监听状态83return0;
84 }
Android.mk
# Copyright 2006 The Android Open Source Project
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
libcutils \
libbinder \
libutils \
libhardware
LOCAL_SRC_FILES:= client.cpp
LOCAL_MODULE_TAGS = eng tests
LOCAL_MODULE:= testClient
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
libcutils \
libbinder \
libutils \
libhardware
LOCAL_SRC_FILES:=server.cpp
LOCAL_MODULE:= testServer
LOCAL_MODULE_TAGS = eng tests
include $(BUILD_EXECUTABLE)
客户端运⾏结果如下:
以上代码参考别⼈写的做了点修改,有错误的地⽅欢迎指出来,谢谢。