C++實例講解Binder通信

  binder是android里面的通信機制,這就不說它如何如何好了,Goog已經說過了,這里不多說。binder是一個面向對象的編程方法,大量使用虛函數類。最近研究binder看到一網友寫的,就借鑒一下。這個例子很好的解釋里binder通信關系。原文:http://blog.csdn.net/new_abc/article/details/8097775 例子不錯不過就是沒運行起來,不過這都不是問題,關鍵是很容易理解。

  我將他的源碼整理類圖看看,不過這個是簡單的繼承關系。

  

  基本上使用binder就這個關系,從中間一分為二,左邊客戶端使用,右邊服務端。不管是客戶端還是服務端都繼承子IXXXService這個類,這個類可以裂解為客戶端和服務端的“爺爺”,而“爺爺”繼承IInterface,所有自定義的binder都必須繼承這個類,這個是android強指針實現計數的方法。先看看源碼后再理解這個圖。

首先看下目錄結構:

  TestBinderClient目錄:? Android.mk??ITestBinderService.cpp

  TestBinderServer目錄: Android.mk??ITestBinderService.h??main_testBinder.cpp??testBinder.cpp??TestBinderService.cpp??TestBinderService.h??

TestBinderClient下面是Binder的客戶端,TestBinderServer是binder的服務端

我們先來看下biner服務端代碼

1、ITestBinderService.h

 1     #ifndef ANDROID_ITESTBINDERSERVICE_H_  
 2     #define ANDROID_ITESTBINDERSERVICE_H_  
 3       
 4     #include <utils/RefBase.h>  
 5     #include <binder/IInterface.h>  
 6     #include <binder/Parcel.h>  
 7       
 8       
 9     namespace android {  
10       
11     class Parcel;  
12       
13     class ITestBinderService: public IInterface {  
14     public:  
15         DECLARE_META_INTERFACE(TestBinderService);  
16       
17         virtual int add(int a, int b) = 0;  
18     };  
19       
20     class BnTestBinderService: public BnInterface<ITestBinderService> {  
21     public:  
22         virtual status_t onTransact(uint32_t code, const Parcel& data,  
23                 Parcel* reply, uint32_t flags = 0);  
24     };  
25       
26     }  
27       
28     #endif /* ANDROID_ITESTBINDERSERVICE_H_ */  
ITestBinderService.h

????? 這里主要是定義了兩個類ITestBinderService 和?BnTestBinderService,ITestBinderService 是TestBinderService 的基類,這里主要是DECLARE_META_INTERFACE 這個宏,定義在frameworks\base\include\binder\IInterface.h文件中。

1 #define DECLARE_META_INTERFACE(INTERFACE)                               \  
2     static const android::String16 descriptor;                          \  
3     static android::sp<I##INTERFACE> asInterface(                       \  
4             const android::sp<android::IBinder>& obj);                  \  
5     virtual const android::String16& getInterfaceDescriptor() const;    \  
6     I##INTERFACE();                                                     \  
7     virtual ~I##INTERFACE();   
DECLARE_META_INTERFACE 宏

把TestBinderService代入進去

1 #define DECLARE_META_INTERFACE(TestBinderService)                               \  
2     static const android::String16 descriptor;                          \  
3     static android::sp<ITestBinderService> asInterface(                       \  
4             const android::sp<android::IBinder>& obj);                  \  
5     virtual const android::String16& getInterfaceDescriptor() const;    \  
6     ITestBinderService();                                                     \  
7     virtual ~I##TestBinderService();  
帶入宏后

其中封裝了實現binder所需要的一些類成員變量和成員函數,通過這些成員函數可以為一個binder實現創建proxy(代理)

2、TestBinderService.h

 1     #ifndef ANDROID_TESTBINDERSERVICE_H_  
 2     #define ANDROID_TESTBINDERSERVICE_H_  
 3       
 4     #include <utils/KeyedVector.h>  
 5     #include "ITestBinderService.h"  
 6       
 7     namespace android {  
 8       
 9     class TestBinderService: public BnTestBinderService {  
10     public:  
11         static void instantiate();  
12         int add(int a,int b);  
13     private:  
14         TestBinderService();  
15         virtual ~TestBinderService();  
16     };  
17       
18     }  
19       
20     #endif /* ANDROID_TESTBINDERSERVICE_H_ */  
TestBinderService.h

這個文件比較簡單,主要就是定義了一個類TestBinderService,繼承于前面 的BnTestBinderService,并定義了一個方法add函數和instantiate

3、TestBinderService.cpp

 1     #define LOG_TAG "TestBinderService"  
 2     #include <utils/Log.h>  
 3     #include <binder/IServiceManager.h>  
 4     #include <binder/IPCThreadState.h>  
 5       
 6     #include "TestBinderService.h"  
 7     static int debug_flag = 1;  
 8     namespace android {  
 9       
10     void TestBinderService::instantiate() {  
11         LOGI("Enter TestBinderService::instantiate");  
12         status_t st = defaultServiceManager()->addService(  
13                 String16("my.test.binder"), new TestBinderService());  
14         LOGD("ServiceManager addService ret=%d", st);  
15         LOGD("instantiate> end");  
16     }  
17       
18     TestBinderService::TestBinderService() {  
19         LOGD(" TestBinderServicet");  
20     }  
21       
22     TestBinderService::~TestBinderService() {  
23         LOGD("TestBinderService destroyed,never destroy normally");  
24     }  
25       
26     int TestBinderService::add(int a,int b) {  
27       
28         LOGI("TestBinderService::add a = %d, b = %d.", a , b);    
29         return a+b;  
30     }  
31  
32  }  
TestBinderService.cpp

在instantiate函數中,將TestBinderService注冊到系統的binder service列表中,這樣以后就可以使用這個service提供的方法,該service提供了一個add 方法,返回兩個數的和。

再來看下clinet端 的代碼

1、ITestBinderService.cpp

 1     #define LOG_TAG "ITeeveePlayerService"  
 2       
 3     #include <utils/Log.h>  
 4       
 5     #include "../TestBinderServer/ITestBinderService.h"  
 6       
 7     namespace android {  
 8       
 9     enum {  
10         TEST_ADD = IBinder::FIRST_CALL_TRANSACTION,  
11     };  
12       
13     class BpTestBinderService: public BpInterface<ITestBinderService> {  
14     public:  
15         BpTestBinderService(const sp<IBinder>& impl) :  
16             BpInterface<ITestBinderService> (impl) {  
17         }  
18       
19         int add(int a, int b) {  
20               
21             Parcel data, reply;  
22             LOGI("Enter BpTestBinderService add,a = %d , b = %d", a, b);  
23             data.writeInterfaceToken(ITestBinderService::getInterfaceDescriptor());  
24             data.writeInt32(a);  
25             data.writeInt32(b);  
26             remote()->transact(TEST_ADD, data, &reply);  
27             int sum = reply.readInt32();  
28             LOGI("BpTestBinderService sum = %d", sum);  
29             return sum;  
30         }  
31     };  
32       
33     IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService");  
34       
35     // ----------------------------------------------------------------------  
36       
37     status_t BnTestBinderService::onTransact(uint32_t code, const Parcel& data,  
38             Parcel* reply, uint32_t flags) {  
39         switch (code) {  
40         case TEST_ADD: {  
41               
42             CHECK_INTERFACE(ITestBinderService, data, reply);  
43             int a = data.readInt32();  
44             int b = data.readInt32();  
45             LOGI("Enter BnTestBinderService add,a = %d , b = %d", a, b);  
46             int sum = 0;  
47             sum  = add(a, b);  
48             LOGI("BnTestBinderService sum = %d", sum);  
49              reply->writeInt32(sum);  
50             return sum;  
51         }  
52         default:  
53             return BBinder::onTransact(code, data, reply, flags);  
54         }  
55     }  
56       
57     }  
ITestBinderService.cpp

定義了一個類BpTestBinderService,提供add方法,該方法通過調用遠端的binder service提供的服務返回兩個數的和重載了BnTestBinderService的onTransact方法,使其在TEST_ADD時調用add方法

這個文件里面也使用了一個宏IMPLEMENT_META_INTERFACE,也是定義在frameworks\base\include\binder\IInterface.h文件中

 1     #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \  
 2         const android::String16 I##INTERFACE::descriptor(NAME);             \  
 3         const android::String16&                                            \  
 4                 I##INTERFACE::getInterfaceDescriptor() const {              \  
 5             return I##INTERFACE::descriptor;                                \  
 6         }                                                                   \  
 7         android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \  
 8                 const android::sp<android::IBinder>& obj)                   \  
 9         {                                                                   \  
10             android::sp<I##INTERFACE> intr;                                 \  
11             if (obj != NULL) {                                              \  
12                 intr = static_cast<I##INTERFACE*>(                          \  
13                     obj->queryLocalInterface(                               \  
14                             I##INTERFACE::descriptor).get());               \  
15                 if (intr == NULL) {                                         \  
16                     intr = new Bp##INTERFACE(obj);                          \  
17                 }                                                           \  
18             }                                                               \  
19             return intr;                                                    \  
20         }                                                                   \  
21         I##INTERFACE::I##INTERFACE() { }                                    \  
22         I##INTERFACE::~I##INTERFACE() { }   
IMPLEMENT_META_INTERFACE宏

代入展開后:

 1 #define IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService")                       \  
 2     const android::String16 ITestBinderService::descriptor("android.test.ITestBinderService");             \  
 3     const android::String16&                                            \  
 4             ITestBinderService::getInterfaceDescriptor() const {              \  
 5         return ITestBinderService::descriptor;                                \  
 6     }                                                                   \  
 7     android::sp<ITestBinderService> ITestBinderService::asInterface(                \  
 8             const android::sp<android::IBinder>& obj)                   \  
 9     {                                                                   \  
10         android::sp<ITestBinderService> intr;                                 \  
11         if (obj != NULL) {                                              \  
12             intr = static_cast<ITestBinderService*>(                          \  
13                 obj->queryLocalInterface(                               \  
14                         ITestBinderService::descriptor).get());               \  
15             if (intr == NULL) {                                         \  
16                 intr = new BpTestBinderService(obj);                          \  
17             }                                                           \  
18         }                                                               \  
19         return intr;                                                    \  
20     }                                                                   \  
21     ITestBinderService::ITestBinderService() { }                                    \  
22     ITestBinderService::~ITestBinderService() { } 
帶入到宏后

這樣,server和client端的binder代碼主寫好了,接著就需要把binder service加入到binder中

這里有兩種方法:

1、在system_init.cpp中添加

TestBinderService::instantiate();

如果是在這里加的話可以去掉TestBinderService中實現的instantiate方法,同時將TestBinderService繼 承自BinderService,因為在BinderService實現了這一方法,同時將其添加到binder service

2、以單獨的程序啟動

main_testBinder.cpp

 1     #include <binder/IPCThreadState.h>  
 2     #include <binder/ProcessState.h>  
 3     #include <binder/IServiceManager.h>  
 4     #include <utils/Log.h>  
 5       
 6       
 7     #include "TestBinderService.h"  
 8       
 9     using namespace android;  
10       
11     int main(int argc, char** argv)  
12      {  
13           
14         sp<ProcessState> proc(ProcessState::self());  
15         sp<IServiceManager> sm = defaultServiceManager();  
16         LOGI("TestBinderService before");  
17         TestBinderService::instantiate();  
18         LOGI("TestBinderService End");  
19         ProcessState::self()->startThreadPool();  
20         IPCThreadState::self()->joinThreadPool();  
21         return 0;  
22       
23     }  
將server添加到servermanage里面

這里調用的是TestBinderService自己的instantiate來添加的

再來看下測試testBinder.cpp

 1     #define LOG_TAG "TestBinserService"  
 2       
 3     #include <utils/Log.h>  
 4     #include <nativehelper/jni.h>  
 5     #include <nativehelper/JNIHelp.h>  
 6     #include <android_runtime/AndroidRuntime.h>  
 7     #include <binder/IServiceManager.h>  
 8     #include "../TestBinderServer/ITestBinderService.h"  
 9       
10       
11     #include "TestBinderService.h"  
12       
13     using namespace android;  
14       
15     int main(int argc, char** argv)  
16      {  
17         int sum = 0;  
18         sp<ITestBinderService> mTestBinserService;  
19         if (mTestBinserService.get() == 0) {  
20             sp<IServiceManager> sm = defaultServiceManager();  
21             sp<IBinder> binder;  
22             do {  
23                 binder = sm->getService(String16("my.test.binder"));  
24                 if (binder != 0)  
25                     break;  
26                     LOGI("getService fail");  
27                 usleep(500000); // 0.5 s  
28             } while (true);  
29             mTestBinserService = interface_cast<ITestBinderService> (binder);  
30             LOGE_IF(mTestBinserService == 0, "no ITestBinserService!?");  
31         }  
32         sum = mTestBinserService->add(3, 4);  
33         LOGI("sum = %d", sum);  
34         return 0;  
35       
36     }  
testBinder.cpp

以上就是測試代碼。

轉載于:https://www.cnblogs.com/winfu/p/5853586.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373947.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373947.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373947.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2014編程之美初賽第一場

題目1 : 焦距 時間限制:2000ms單點時限:1000ms內存限制:256MB描述 一般來說&#xff0c;我們采用針孔相機模型&#xff0c;也就是認為它用到的是小孔成像原理。 在相機坐標系下&#xff0c;一般來說&#xff0c;我們用到的單位長度&#xff0c;不是“米”這樣的國際單位&#x…

高中python公開課怎么上好_如何上好高中英語公開課

談如何上好高中英語公開課對青年教師來說&#xff0c;開一節公開課&#xff0c;如同完成一次蛻變&#xff0c;累掉一層皮&#xff0c;有著刻骨銘心的陣痛&#xff0c;但換來的是突飛猛進的專業成長。可以說&#xff0c;公開課是青年教師培訓的有效途徑&#xff0c;是名師培養的…

Codeforces Round #261 (Div. 2) - E (459E)

題目連接&#xff1a;http://codeforces.com/contest/459/problem/E 題目大意&#xff1a;給定一張有向圖&#xff0c;無自環無重邊&#xff0c;每條邊有一個邊權&#xff0c;求最長嚴格上升路徑長度。(1≤n&#xff0c;m≤3 *10^5) 初見此題覺得以邊為點&#xff0c;以點為邊&…

回收對象以提高性能

總覽 在上一篇文章中&#xff0c;我說過對象反序列化更快的原因是由于使用了回收對象。 由于兩個原因&#xff0c;這可能令人驚訝&#xff1a;1&#xff09;相信如今創建對象是如此之快&#xff0c;無關緊要或與回收自己一樣快&#xff0c;2&#xff09;默認情況下&#xff0c;…

jquery GET POST

<!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <head> <!--引入百度庫--> <script src"http://libs.baidu.com/jquery/1.10.2/jquery.min.js"> </script> <title></title> <scrip…

C++高精度運算類bign (重載操作符)

大數據操作&#xff0c;有如下問題&#xff1a; 計算&#xff1a;45678913561232654213212314875231656511323132 456789135612326542132123*14875231656511323132 比較&#xff1a;7531479535511335666686565>753147953551451213356666865 ? long long類型存儲不了&…

oj系統格式錯誤_論文查重會不會檢查格式?【paperpp吧】

高等學校一般都會要求大學生在畢業時需要寫作畢業論文&#xff0c;并且會提前發出關于畢業論文的通知&#xff0c;在通知上一般會說明論文寫作的相關要求&#xff0c;其中就會規定論文的相關格式。當然&#xff0c;學校也會在通知中說明論文查重的相關事宜&#xff0c;那么論文…

JavaScript Cookies

相關&#xff1a;jquery-cookie cookie 是存儲于訪問者的計算機中的變量&#xff0c;常用來存儲用戶名字&#xff0c;密碼&#xff0c;日期&#xff0e; 示例&#xff1a; 1 document.cookie"usernameJohn Doe"; 2 document.cookie"usernameJohn Doe; expiresTh…

大數據 -- Hadoop集群搭建

Hadoop集群搭建 1.修改/etc/hosts文件 在每臺linux機器上&#xff0c;sudo vim /etc/hosts 編寫hosts文件。將主機名和ip地址的映射填寫進去。編輯完后&#xff0c;結果如下&#xff1a; 2.配置ssh&#xff0c;實現無密碼登錄 四臺虛擬機上&#xff0c;使用&#xff1a; ssh-ke…

通過示例休眠–第2部分(DetachedCriteria)

所以上次我們幫助正義聯盟有效地管理了他們的超級英雄。 今天&#xff0c;我們集中討論“復仇者聯盟”將如何使用冬眠的“分離標準”找出每個超級英雄的敵人&#xff0c;以保護他們的超級英雄。 您可以從此處下載工作示例。 在此示例中&#xff0c;我們僅考慮兩個實體。 復仇者…

2014編程之美初賽第二場

題目1 : 神奇的數列 時間限制:2000ms單點時限:1000ms內存限制:256MB描述 大神同學是一個熱愛數字的孩子&#xff0c;她無時無刻不在思考生活與數學的聯系。有一天&#xff0c;她發現其實公歷的設計是有講究的。 每4年就會多閏一天&#xff0c;每一百年又會有一年不是閏年&#…

usb大容量存儲設備驅動_usb無法識別怎么辦 如何解決usb識別故障【詳細步驟】...

usb無法識別怎么辦? 隨著計算機硬件飛速發展&#xff0c;外圍設備日益增多&#xff0c;鍵盤、鼠標等早已為人所共知&#xff0c;數碼相機、MP3隨身聽接踵而至&#xff0c;這么多的設備&#xff0c;如何接入個人計算機?USB就是基于這個目的產生的。USB是一個使計算機周邊設備連…

CSDN編程挑戰——《交替字符串》

交替字符串 題目詳情: 如果字符串str3能夠由str1和str2中的字符按順序交替形成&#xff0c;那么稱str3為str1和str2的交替字符串。例如str1"abc"&#xff0c;str2"def"&#xff0c;那么"adbecf", "abcdef", "abdecf", "…

hdu-5834 Magic boy Bi Luo with his excited tree(樹形dp)

題目鏈接&#xff1a; Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1037 Accepted Submission(s): 298 Problem DescriptionBi Luo is a magic boy, he also has …

Java EE過去,現在和云7

最近的JavaOne 2011的一個突出主題是下一個主要的Java EE 7版本。 正如主題發言中所述&#xff0c;有關工作正在進行中。 它將包含我們已經從先行者那里知道的28個規范以及一些新規范。 沒人可以告訴您確切的號碼&#xff0c;因為EE 7僅在“及時”完成時才會接受新的規范。 這意…

python cnn識別圖像_笨方法學習CNN圖像識別(一)—— 圖片預處理

— 全文閱讀5分鐘 —在本文中&#xff0c;你將學習到以下內容&#xff1a;通過數據增強增加樣本量調整圖片大小便于網絡訓練前言圖像識別的準備工作就是要對我們拿到手的樣本圖片進行預處理&#xff0c;具體就是數據增強和調整圖片大小&#xff0c;這些準備工作都是為訓練網絡做…

隨機數發生器

很多人喜歡用 rand()%n產生區間 [0,n]內的一個隨機整數。姑且不論這樣產生的整數是否仍然均勻分布&#xff0c;當 n大于 RAND_MAX 時&#xff0c;此法并不能得到期望的結果。由于RAND_MAX 很可能只是32767這么小&#xff0c;在使用此法時應當小心。 #include "stdio.h&quo…

Request和Response詳解

轉自&#xff1a;http://zhidao.baidu.com/link?url8BI0cjlcFdBSJKHTZlpo874eqtbTJoZfrh3miQgM_05RvSER8skPiBc1wSPZtXT8OGGCHfVXFAzAosa6E5HBl_ 內置對象request&#xff1a;請求對象request.getParameter("名字") 獲得客戶端輸入的信息***************request.get…

將Maven與Ivy集成

問題是&#xff1a;您在Ivy存儲庫中&#xff08;只有那里&#xff09;有一些資源&#xff0c;您想在基于Maven的項目中使用這些資源。 可能的解決方案&#xff1a; 由于Ivy可以輕松使用Maven風格的存儲庫&#xff08;因此&#xff0c;您的Ivy客戶端可以繼續使用Ivy并進行一些微…

用python下載辭典

用python下載詞源詞典Etymoline Online Etymology Dictionary是最好的 English 詞源詞典&#xff0c;現在來說沒有之一。但是&#xff0c;一直在PC上查單詞有時不是很方便&#xff0c;遂就想怎么才能在手機上使用。現在的手機上的詞典&#xff0c;除了BlueDict、MDict之外&…