亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Binder工作機制詳解(應用層)

2019-11-09 14:16:28
字體:
來源:轉載
供稿:網友

轉載請注明出處:http://blog.csdn.net/wu371894545/article/details/54962860

一、Binder機制概述

在Android開發中,很多時候我們需要用到進程間通信,所謂進程間通信,實現進程間通信的機制有很多種,比如說socket、pipe等,Android中進程間通信的方式主要有三種:

1.標準linux Kernel IPC 接口;

2.標準D-BUS接口;

3.Binder接口。

其中,Binder機制是使用最且最被認可的,因為Binder機制有以下優點:

1.相對于其它IPC機制,Binder機制更加簡潔和快速;

2.消耗的內存相對更少;

3.傳統的IPC機制可能會增加進程的開銷,以及出現進程過載和安全漏洞,Binder機制則有效避免和解決了這些問題。

Binder機制是Android系統的核心機制,幾乎貫穿于整個Android系統,Android系統基本上可以看作是一個基于binder通信機制的C/S架構,Binder就像網絡,把Android系統的各個部分連接到了一起。利用Binder機制,可以實現以下功能:

1.用驅動程序來推進進程間通信;

2.通過共享內存來提高性能;

3.為進程請求分配每個進程的線程池;

4.針對系統中的對象引入了引用計數和跨進程的對象引用映射;

5.進程間同步調用。

二.什么是Binder

1. 直觀來說,Binder是Android中的一個類,它繼承了IBinder接口

2. 從IPC角度來說,Binder是Android中的一種跨進程通信方式,Binder還可以理解為一種虛擬的物理設備,它的設備驅動是/dev/binder,該通信方式在Linux中沒有

3. 從Android Framework角度來說,Binder是ServiceManager連接各種Manager(ActivityManager、WindowManager,etc)和相應ManagerService的橋梁

4. 從Android應用層來說,Binder是客戶端和服務端進行通信的媒介,當你bindService的時候,服務端會返回一個包含了服務端業務調用的Binder對象,通過這個Binder對象,客戶端就可以獲取服務端提供的服務或者數據,這里的服務包括普通服務和基于AIDL的服務

三、為什么Android內核要使用Binder

Android中有大量的CS(Client-Server)應用方式,這就要求Android內部提供IPC方法,而linux所支持的進程通信方式有兩個問題:性能和安全性。

目前linux支持的IPC包括傳統的管道,System V IPC(消息隊列/共享內存/信號量),以及socket,但只有socket支持Client-Server的通信方式,由于socket是一套通用的網絡通信方式,其傳輸效率低下切有很大的開銷,比如socket的連接建立過程和中斷連接過程都是有一定開銷的。消息隊列和管道采用存儲-轉發方式,即數據先從發送方緩存區拷貝到內核開辟的緩存區中,然后再從內核緩存區拷貝到接收方緩存區,至少有兩次拷貝過程。共享內存雖然無需拷貝,但控制復雜,難以使用。

在安全性方面,Android作為一個開放式,擁有眾多開發者的的平臺,應用程序的來源廣泛,確保智能終端的安全是非常重要的。終端用戶不希望從網上下載的程序在不知情的情況下偷窺隱私數據,連接無線網絡,長期操作底層設備導致電池很快耗盡等等。傳統IPC沒有任何安全措施,完全依賴上層協議來確保。首先傳統IPC的接收方無法獲得對方進程可靠的UID/PID(用戶ID/進程ID),從而無法鑒別對方身份。Android為每個安裝好的應用程序分配了自己的UID,故進程的UID是鑒別進程身份的重要標志。使用傳統IPC只能由用戶在數據包里填入UID/PID,但這樣不可靠,容易被惡意程序利用。可靠的身份標記只有由IPC機制本身在內核中添加。其次傳統IPC訪問接入點是開放的,無法建立私有通道。比如命名管道的名稱,system V的鍵值,socket的ip地址或文件名都是開放的,只要知道這些接入點的程序都可以和對端建立連接,不管怎樣都無法阻止惡意程序通過猜測接收方地址獲得連接。

基于以上原因,Android需要建立一套新的IPC機制來滿足系統對通信方式,傳輸性能和安全性的要求,這就是Binder。Binder基于 Client-Server通信模式,傳輸過程只需一次拷貝,為發送發添加UID/PID身份,既支持實名Binder也支持匿名Binder,安全性高。

二、從自動生成的AIDL文件中分析Binderpackage com.ryg.chapter_2.aidl;public interface IBookManager extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.ryg.chapter_2.aidl.IBookManager { PRivate static final java.lang.String DESCRIPTOR = "com.ryg.chapter_2.aidl.IBookManager"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.ryg.chapter_2.aidl.IBookManager * interface, generating a proxy if needed. */ public static com.ryg.chapter_2.aidl.IBookManager asInterface( android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.ryg.chapter_2.aidl.IBookManager))) { return ((com.ryg.chapter_2.aidl.IBookManager) iin); } return new com.ryg.chapter_2.aidl.IBookManager.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getBookList: { data.enforceInterface(DESCRIPTOR); java.util.List<com.ryg.chapter_2.aidl.Book> _result = this .getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); com.ryg.chapter_2.aidl.Book _arg0; if ((0 != data.readInt())) { _arg0 = com.ryg.chapter_2.aidl.Book.CREATOR .createFromParcel(data); } else { _arg0 = null; } this.addBook(_arg0); reply.writeNoException(); return true; } case TRANSACTION_registerListener: { data.enforceInterface(DESCRIPTOR); com.ryg.chapter_2.aidl.IOnNewBookArrivedListener _arg0; _arg0 = com.ryg.chapter_2.aidl.IOnNewBookArrivedListener.Stub .asInterface(data.readStrongBinder()); this.registerListener(_arg0); reply.writeNoException(); return true; } case TRANSACTION_unregisterListener: { data.enforceInterface(DESCRIPTOR); com.ryg.chapter_2.aidl.IOnNewBookArrivedListener _arg0; _arg0 = com.ryg.chapter_2.aidl.IOnNewBookArrivedListener.Stub .asInterface(data.readStrongBinder()); this.unregisterListener(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.ryg.chapter_2.aidl.IBookManager { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public java.util.List<com.ryg.chapter_2.aidl.Book> getBookList() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.util.List<com.ryg.chapter_2.aidl.Book> _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0); _reply.readException(); _result = _reply .createTypedArrayList(com.ryg.chapter_2.aidl.Book.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void addBook(com.ryg.chapter_2.aidl.Book book) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((book != null)) { _data.writeInt(1); book.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void registerListener( com.ryg.chapter_2.aidl.IOnNewBookArrivedListener listener) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeStrongBinder((((listener != null)) ? (listener .asBinder()) : (null))); mRemote.transact(Stub.TRANSACTION_registerListener, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void unregisterListener( com.ryg.chapter_2.aidl.IOnNewBookArrivedListener listener) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeStrongBinder((((listener != null)) ? (listener .asBinder()) : (null))); mRemote.transact(Stub.TRANSACTION_unregisterListener, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_registerListener = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); static final int TRANSACTION_unregisterListener = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); } public java.util.List<com.ryg.chapter_2.aidl.Book> getBookList() throws android.os.RemoteException; public void addBook(com.ryg.chapter_2.aidl.Book book) throws android.os.RemoteException; public void registerListener( com.ryg.chapter_2.aidl.IOnNewBookArrivedListener listener) throws android.os.RemoteException; public void unregisterListener( com.ryg.chapter_2.aidl.IOnNewBookArrivedListener listener) throws android.os.RemoteException;}(1):首先,它申明了倆個方法getBookList和addBook,顯然這就是我們在IbookManager.aidl中所申明的方法。同時它還倆個整形的id分別用于表示這倆個方法。(2):接著,它申明了一個內部類Stub,這個Stub就是一個Binder類,當客戶端和服務端都位于同一個進程時,方法調用不會走跨進程的transact過程,而當倆者位于不同進程時,方法調用走transact過程,這個邏輯是由于Stub的內部代理類Proxy來完成。這么看來,IbookManager這個接口的確很簡單,但是我們也應該認識到,這個接口的核心實現就是它的內部類Stub和Stub的內部代理類Proxy.DESCRIPTORBinder的唯一標識,一般用當前Binder的類名表示,比如本例中的com.ryg.chapter_2.aidl.IBookManagerasInterface用于將服務端的Binder對象轉換成客戶端所需的AIDL接口對象的類型,這種轉換過程是區分進程的,如果客戶端和服務端位于同一進程,那么此方法返回的就是服務端的Stub對象本身,否則返回的就是系統封裝后的Stub.proxy對象。asBinder此方法返回當前Binder對象onTransact這個方法運行在服務端中的Binder線程池中,當客戶端發起跨進程請求時,遠程請求會通過底層封裝后交由此方法來處理。服務端通過code可以確定客戶端所請求的目標到底是什么。當目標方法執行完畢后,就向reply中寫入返回值。需要注意的是,如果此方法返回false,那么客戶端的請求會失敗,因此我們可以利用這個特性來進行權限認證,畢竟我們也不希望隨便一個進程都能遠程調用我們的服務。雖然我們知道了BInder的工作機制,但是還需要說明倆點:1.當客戶端發起遠程請求時,由于當前線程會被掛起直至服務端進程返回數據,所以如果一個遠程方法很耗時,那么不能在UI線程中發起此遠程請求。2.由于服務器的Binder方法運行在Binder線程池,所以Binder方法不管是否耗時都應該采用同步的方式去實現。,因為它已經運行在一個線程中了。

四、Binder機制的工作流程

從上面我們可以知道Binder工作機制的流程:

1.客戶端獲取服務端的帶來對象(proxy)。我們需要明確的是客戶端進程并不能直接操作服務端中的方法,如果要操作服務端中的方法,那么有一個可行的解決方法就是在客戶端建立一個服務端進程的代理對象,這個代理對象具備和服務端進程一樣的功能,要訪問服務端進程中的某個方法,只需要訪問代理對象中對應的方法即可;

2.客戶端通過調用代理對象向服務端發送請求。

3.代理對象將用戶請求通過Binder驅動發送到服務器進程;

4.服務端進程處理客戶端發過來的請求,處理完之后通過Binder驅動返回處理結果給客戶端的服務端代理對象;

5.代理對象將請求結果進一步返回給客戶端進程。

通過以上5個步驟,就完成了一次Binder通信。

下面我們給出一張Binder的工作機制圖

 源碼下載
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品精品一区二区三区午夜版| 综合国产在线视频| 国产一区二区在线免费| 亚洲在线观看视频网站| 国产精品日日做人人爱| 国产欧美在线看| 伊人精品在线观看| 热久久99这里有精品| 国产午夜精品视频| 狠狠躁夜夜躁久久躁别揉| 亚洲一区二区自拍| 77777少妇光屁股久久一区| 日韩精品在线观看视频| 国产日韩欧美中文| 欧洲日韩成人av| 国产区精品在线观看| 欧美精品在线看| 91欧美视频网站| 国产成人精品视频在线| 高清日韩电视剧大全免费播放在线观看| 国产一区私人高清影院| 日韩欧美成人免费视频| 中国日韩欧美久久久久久久久| 国产精品白嫩美女在线观看| 欧美国产欧美亚洲国产日韩mv天天看完整| 色偷偷噜噜噜亚洲男人的天堂| 欧美性生活大片免费观看网址| 国产日韩中文字幕| 97欧美精品一区二区三区| 国产成人+综合亚洲+天堂| 亚洲偷熟乱区亚洲香蕉av| 亚洲精品日产aⅴ| 国产精品日韩欧美大师| 日韩电影免费在线观看中文字幕| 成人性生交大片免费看视频直播| 国产一区二区三区在线观看视频| 亚洲欧美日韩高清| 日韩在线观看成人| 国产97色在线|日韩| 久久九九全国免费精品观看| 91免费看片在线| 性欧美长视频免费观看不卡| 欧美性受xxxx白人性爽| 久久久亚洲福利精品午夜| 日韩极品精品视频免费观看| 欧美日韩高清区| 亚洲国产精品国自产拍av秋霞| 久久天天躁狠狠躁老女人| 国模gogo一区二区大胆私拍| yellow中文字幕久久| 日本国产精品视频| 日本91av在线播放| 最近2019中文字幕第三页视频| 91色在线视频| 亚洲欧洲国产伦综合| 久久久国产91| 日韩精品中文字幕久久臀| 国产脚交av在线一区二区| 国产精品久久久久久一区二区| 日韩欧美在线看| 国产91在线播放九色快色| 成人乱色短篇合集| 国产精品尤物福利片在线观看| 久久精品国产一区二区电影| 欧美亚洲午夜视频在线观看| 欧美激情精品久久久久久变态| 精品久久久香蕉免费精品视频| 久久香蕉国产线看观看网| 91亚洲精品久久久久久久久久久久| 成人中文字幕+乱码+中文字幕| 国产三级精品网站| 国产精品91久久久久久| 91精品国产一区| 亚洲国产欧美一区二区三区同亚洲| 欧美亚洲国产日韩2020| 成人字幕网zmw| 久久久久一本一区二区青青蜜月| 欧美午夜电影在线| 成人美女免费网站视频| 日韩亚洲欧美中文高清在线| 国产大片精品免费永久看nba| 亚洲伊人久久大香线蕉av| www.美女亚洲精品| 国产欧美最新羞羞视频在线观看| 色一情一乱一区二区| 国产精品自在线| 性欧美长视频免费观看不卡| 亚洲欧美综合精品久久成人| 最近2019免费中文字幕视频三| 国产精品旅馆在线| 永久免费毛片在线播放不卡| 亚洲天堂av电影| 尤物yw午夜国产精品视频明星| 国产成人激情视频| 国产福利视频一区| 韩国三级电影久久久久久| 成人在线中文字幕| 日韩精品在线电影| 日韩中文字幕网站| 国产精品网红直播| 久久久国产精彩视频美女艺术照福利| 中文字幕国产亚洲2019| 国产有码在线一区二区视频| 欧美巨乳在线观看| 国产精品91久久久| 538国产精品一区二区免费视频| 亚洲一区二区三区在线视频| 亚洲欧美在线x视频| 久久影院中文字幕| 欧美特黄级在线| 国产丝袜一区二区三区| 一区二区三区美女xx视频| 欧美天堂在线观看| 日韩精品视频免费专区在线播放| 欧美国产欧美亚洲国产日韩mv天天看完整| 欧美激情视频在线免费观看 欧美视频免费一| 91精品视频在线免费观看| 成人黄色免费片| 成人亲热视频网站| 韩国三级电影久久久久久| 欧美做受高潮电影o| 久久久久久com| 日本一区二区三区四区视频| 国产91在线高潮白浆在线观看| 国产综合在线观看视频| 色偷偷噜噜噜亚洲男人的天堂| 日韩精品在线视频美女| 欧美在线亚洲在线| 国产精品美女www爽爽爽视频| 亚洲网在线观看| 国产精品一二三视频| 日韩成人av一区| 欧美日韩免费网站| 国产欧美日韩精品专区| 精品国产一区二区三区久久狼5月| 国产精品视频男人的天堂| 96国产粉嫩美女| 亚洲无av在线中文字幕| 久久五月情影视| 中文字幕日韩av| 午夜精品三级视频福利| 日韩av男人的天堂| 欧美肥老太性生活视频| 欧美二区乱c黑人| 国产精自产拍久久久久久蜜| 亚洲第一精品久久忘忧草社区| 97在线观看视频| 亚洲精品视频在线观看视频| 精品久久久久久久久久久久| 国产精品久久久久久久久免费看| 永久免费毛片在线播放不卡| www.午夜精品| 91在线网站视频| 久久久噜噜噜久噜久久| 亚洲一品av免费观看| 国产精品ⅴa在线观看h| 色阁综合伊人av| 色一情一乱一区二区| 成人免费视频a| 欧美人成在线视频| 精品国产一区二区三区久久| 亚洲精品久久久久久久久| 亚洲视频在线观看网站| 91欧美日韩一区|