標籤:map 實現 輕量級 檔案 main linux 進程 throw files 元素
摘要:對 Binder 工作機制進行了分析。 首先簡述 Android 中 Binder 機制與傳統的 Linux 進程間的通訊比較,接著對基於 Binder 處理序間通訊的過程分析 最後結合開發執行個體 (AIDL),瞭解 基於 Binder的處理序間通訊。
1、Android 採用 Binder 作為 IPC (Internet Process Connection) 機制的優勢
Linux已經擁有的處理序間通訊IPC手段包括(Internet Process Connection): 管道、訊號和跟蹤、插口、報文隊列、共用記憶體和訊號量。但是Linux 處理序間通訊方式存在著增加進程的開銷、 進程過載和安全性漏洞等方面的問題。在 Android 系統中,Binder IPC 處理序間通訊機制可以有效地解決這些問題。
Binder的優勢:
①高效率: Binder 傳輸只需要一次拷貝,而管道、訊息佇列、Socket都需要拷貝兩次,對於行動裝置,效能一直是個大問題;
②安全性高: Binder 機制對於通訊雙方的身份是核心進行校檢支援的,socket 方式只需要知道地址都可以串連;
③易用性: B/S模式的通訊,如果管道/訊息佇列還得進行封裝,而Binder使用物件導向的方式設計,進行一次遠端程序呼叫就像調用本機物件;
2、基於 Binder 處理序間通訊的過程分析
Binder IPC 方式使得兩個進程間的通訊像是一個進程進入另外一個進程執行代碼, 並帶著運行結果返回,這類似於一個“輕量級” 的遠程調用過程 。
Binder 機制是通過 Server /Client 架構實現的,主要包括Server,Client,Service Manager以及Binder驅動。其中Server,Client,Service Manager運行於使用者空間,驅動運行於核心空間。(如)
3、結合開發執行個體 (AIDL)
3.1 案例需求假設
一個應用的 Service 提供一本書名的資訊的遠程服務,作為服務端,另外一個應用中的 Activity 想擷取 一本書名的資訊。 Android的資料傳遞採用 Aidl 的方式。
3.2 案例分析
Android 的不同應用不能共用資料, 因此如果有需要的話只能通過進程間通訊來完成應用共用資料。
進程間通訊(ipc)涉及到三個部分:用戶端(調用方),傳遞資料,服務(被呼叫者)。其中服務端 Service 被同一個應用調用和不同應用調用原理是不同的。
因此分成以下兩種:
①本地服務(Local Service):Service 被同一個應用中的 Activity 調用,用於實現應用程式自己的一些耗時任務。
②遠程服務(Remote Sercie):可以被其他應用程式複用,比如 WiFi 服務,其他應用程式不需要再寫這樣的服務,調用已有的即可。
該案例選擇本地服務即可。
3.3 AIDL案例實現原理
從Android應用程式層來說,Binder是用戶端和服務端進行通訊的媒介,當你bindService的時候,服務端會返回一個包含了服務端業務調用的Binder對象。
通過這個Binder對象,用戶端就可以擷取服務端提供的服務或者資料。(如)
3.4 AIDL案例實現步驟
①建立一個BookInfo類 繼承Service
②建立一個IBookInfo介面,寫對應的AIDL檔案的方法
private String getNames(){ Log.e("JianChengLoveBianCheng", "MyService.getName"); return "《平凡的世界》"; }
③在功能資訊清單檔中註冊服務
<service android:name="com.example.aidl.BookInfo" > <intent-filter> <action android:name="com.JCLoveBiancheng.binder.action.AIDLService" /> </intent-filter> </service>
④將AIDL 檔案產生的類,在服務中綁定
private final IBookInfo.Stub mBinder = new IBookInfo.Stub() { @Override public String getName() throws RemoteException { Log.e("JianChengLoveBianCheng", "MyService.AIDLService.getName"); return getNames(); } }; //找不到IBookInfo的話,rebuild project即可
⑤綁定方式啟動Service
private IBookInfo mService;//服務的代理類 private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { Log.e("JCLoveBiancheng", "MainActivity.onServiceConnected"); mService = IBookInfo.Stub.asInterface(service); } public void onServiceDisconnected(ComponentName className) { Log.e("JCLoveBiancheng", "MainActivity.onServiceDisconnected"); mService = null; } };
⑦開啟服務
Intent intent = new Intent(MainActivity.this,BookInfo.class); intent.setAction("com.JCLoveBiancheng.binder.action.AIDLService"); bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
⑧點擊按鈕即可從服務中擷取資訊(如)
點擊Bind服務列印出:
點擊UnBind服務列印出:
點擊擷取資訊列印出:
附加:
AIDL 支援的資料類型
基礎資料型別 (Elementary Data Type):int、long、char、boolean、double 、String 和 CharSequence
List:
只支援ArrayList,裡面的每一個元素都必須能夠被 AIDL 支援
Map:
只支援 HashMap,裡面的每一個元素都必須能夠被 AIDL 支援
Parcelable:
所有實現了 Parcelable 介面的對象
AIDL:
所有的 AIDL 介面本身也可以在 AIDL檔案中使用。
Demo: http://files.cnblogs.com/files/wujiancheng/aidl%E5%B0%8F%E6%A1%88%E4%BE%8B.zip
Android 中基於 Binder的處理序間通訊