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>
  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)

客户端运行结果如下:

 以上代码参考别人写的做了点修改,有错误的地方欢迎指出来,谢谢。

posted @ 2016-08-02 15:38  winfu  阅读(4703)  评论(1编辑  收藏  举报