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>
7 using 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
19 class MyService : public BBinder
20 {
21 public:
22 MyService()
23 {
24 mydescriptor = String16("media.hello");
25 n=0;
26 }
27 virtual ~MyService() {}
28 //This function is used when call Parcel::checkInterface(IBinder*)
29 virtual const String16& getInterfaceDescriptor() const
30 {
31 LOGE("this is enter ==========getInterfaceDescriptor");
32 return mydescriptor;
33 }
34 protected:
35 void 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 }
43 virtual 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 */
55 switch (code)
56 {
57 case 1:
58 LOGD("MyService interface 1");
59 break;
60 case 2:
61 LOGD("MyService interface 2");
62 cb = data.readStrongBinder();
63 break;
64 case 3:
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);
70 break;
71 }
72 case 4:
73 {//call cb
74 LOGD("MyService interface 4 before if================");
75 cb = data.readStrongBinder();
76 if (cb != NULL)
77 {
78 LOGD("MyService interface 4");
79 Parcel in, out;
80 in.writeInterfaceToken(String16("android.os.ISetupCallback"));
81 in.writeInt32(n++); //向客户端发送数据
82
83 in.writeCString("This is a string !");
84 cb->transact(2, in, &out, 0);
85 show();
86 }
87 break;
88 }
89 default:
90 return BBinder::onTransact(code, data, reply, flags);
91 }
92 return 0;
93 }
94 private:
95 String16 mydescriptor;
96 sp<IBinder> cb;
97 int n;
98 };
99 int 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,进入服务的循环监听状态
110 return 0;
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
9 using 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
21 class MySetupCallback : public BBinder
22 {
23 public:
24 MySetupCallback()
25 {
26 mydescriptor = String16("android.os.ISetupCallback");
27 }
28 virtual ~MySetupCallback() {}
29 virtual const String16& getInterfaceDescriptor() const
30 {
31 return mydescriptor;
32 }
33 protected:
34 virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
35 {
36 LOGD("enter MySetupCallback onTransact, code=%u", code);
37 if (data.checkInterface(this)) //检查 mydescriptor 类描述字符串
38 LOGD("checkInterface OK");
39 else
40 {
41 LOGW("checkInterface failed");
42 return -1;
43 }
44 switch (code) //code为服务器发送的code,根据code实现不同的函数
45 {
46 case 1:
47 LOGD("From Server code = %u", code);
48 LOGD("From Server code = %u", code);
49 break;
50 case 2:
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
56 break;
57 }
58 default:
59 break;
60 }
61 return 0;
62 }
63 private:
64 String16 mydescriptor;
65 };
66
67 int main()
68 {
69 sp<IServiceManager> sm = defaultServiceManager(); //获取ServiceManager服务代理
70 sp<IBinder> b = sm->getService(String16("media.hello")); //查询服务
71 if (b == NULL)
72 {
73 LOGW("Can't find binder service \"media.hello\"");
74 return -1;
75 }
76 Parcel in1,out1;
77 MySetupCallback *cb = new MySetupCallback();
78 in1.writeStrongBinder(sp<IBinder>(cb));
79 int 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,进入服务的循环监听状态
83 return 0;
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)
客户端运行结果如下:
以上代码参考别人写的做了点修改,有错误的地方欢迎指出来,谢谢。
原文链接: https://www.cnblogs.com/winfu/p/5729524.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/237983
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!