❶ 如何在android中使用AIDL設計遠程介面麻煩告訴我
在Android平台,一個進程通常不能訪問另一個進程的內存空間,所以要想對話,需要將對象分解成操作系統可以理解的基本單元,並且有序地通過進程邊界。
通過代碼來實現這個數據傳輸過程是冗長乏味的,Android提供了AIDL工具來處理這項工作。AIDL()是一種IDL語言,用於生成可以在Android設備上兩個進程之間進行進程間通信(IPC)的代碼。如果在一個進程中(例如Activity)要調用另一個進程中(例如Service)對象的操作,就可以使用AIDL生成可序列化的參數。AIDLIPC機制是面向介面的,像COM或Corba一樣,但是更加輕量級。它是使用代理類在客戶端和實現端傳遞數據。
一、使用AIDL實現IPC(ImplementingIPCUsingAIDL)
使用AIDL實現IPC服務的步驟是:第一,創建.aidl文件。該文件(YourInterface.aidl)定義客戶端可用的方法和數據介面。第二,在makefile文件中加入.aidl文件(Eclipse中的ADT插件提供管理功能)。Android包括名為AIDL的編譯器,位於tools/文件夾。第三,實現介面-AIDL編譯器從AIDL介面文件中利用java語言創建介面。該介面有一個繼承的命名為Stub的內部抽象類(已實現一些IPC調用的附加方法),要做的就是創建一個繼承於YourInterface.Stub的類,並且實現在.aidl文件中聲明的方法。第四,向客戶端公開介面。如果是編寫服務,應該繼承Service並且重載Service.onBind(Intent)以返回實現了介面的對象實例。
二、創建.aidl文件(Createan.aidlFile)
AIDL使用簡單的語法來聲明介面,描述其方法以及方法的參數和返回值。這些參數和返回值可以是任何類型,甚至是其他AIDL生成的介面。需要注意的是,必須導入所有非內置類型。AIDL能支持的數據類型有以下幾類:第一,Java編程語言的主要類型(int,boolean等),不需要import語句。第二,通常引引用方式傳遞的其他AIDL生成的介面,必須要import語句聲明。第三,實現了Parcelableprotocol以及按值傳遞的自定義類,必須要import語句聲明。另外,還有一些不需要import語句,如String等。
三、實現介面(ImplementingtheInterface)
AIDL生成了與.aidl文件同名的介面,如果使用Eclipse插件,AIDL會作為編譯碰歷過程的一部分自動運行(不需要先運行AIDL再編譯項目);如果沒有插件,就要先運行AIDL。
生成的介麵包含一個名為Stub的抽象的內部類,該類聲明了所有.aidl中描述的方法,Stub還定義了少量的輔助方法,尤其是asInterface(),通過它獲得IBinder(當applicationContext.bindService()成功調用時傳遞到客戶端的onServiceConnected())並且返回用於調用IPC方法的介面實例。要實現自己的介面,就從YourInterface.Stub類繼承,然笑蠢搜後實現相關方法(可以創建.aidl文件實現stub方法而不用在中間編譯,Android編譯過程會在.java文件之前處理.aidl文件)。
在完成了介面的實現後,需要向客戶端暴露介面,也就是發布服務。實現的方法是繼承Service,然後檔知實現以Service.onBind(Intent)返回一個實現了介面的類對象。下面的代碼片斷表示了暴露IRemoteService介面給客戶端的方式。如果有類想要能過AIDL在進程之間傳遞,這一想法是可以實現的,但必須確保這個類在IPC的兩端的有效性。
以上是筆者對《Android中使用AIDL設計遠程介面》的一些思路與實現方法。筆者認為,由於Android自身的集成性、控制性、交互性等特點,可以激發學生的學習的興趣,調動學生的積極參與,擴大學生知識面,提供多種學習的路徑。
(作者單位:鎮江技師學院)
❷ Android:AIDL進程間通信基本框架
在某些業務場景下,我們需要在應用中單獨開啟一個進程進行一些操作。比如性能監控,如果讓原始業務和性能監控本身的業務跑在同一個進程下,那麼就會導致性能統計的數據的失真。
而進程間通信,一般採用AIDL機制的客戶端與服務端通信。
AIDL只能傳遞如下幾類數據:
當傳遞自定義 Parcelable 時,有三處地方需要注意:
當傳遞其他 aidl 介面時,同樣必須要 import 這個 aidl 文件
編寫完 aidl 文件後,make一下工程,會在 build 下的 generated 下的 source 下的 aidl 目錄生成對應的介面類文件。aidl 介面其實就是 API 介面,通過實現對應介面類的 Stub 子類來實現具體的 API 邏輯;通過對應介面類的 Stub 子類的 asInterface 方法得到具體的實現類,調用具體的 API 方法。
一個基本的客戶端服務端的通信結構一般包括如下功能
客戶端的功能
服務端的功能
客戶端的相關功能實現比較簡單,麻煩的是服務端的功能。因為 AIDL 介面定義的都是服務端的介面,是由客戶端來調用的。而想要實現服務端反向調用客戶端則需要通過其他手段實現。
想要實現服務端主動連接客戶端,最好的辦法就是 服務端發送廣播,客戶端收到廣播後再主動連接服務端 ,通過這種方式變相地實現服務端主動連接客戶端的功能
想要實現服務端主動斷開客戶端,除了上面 發送廣播是一種實現方式外,還可以通過 android 的系統API RemoteCallbackList,用包名作為key值來注冊遠程回調介面的方式,讓服務端持有客戶端的回調介面,服務端調用回調介面,客戶端在回調介面中實現主動斷開服務端 ,通過這種方式變數地實現服務端主動斷開客戶端的功能。而採用後者會顯得更加優雅
既然所有的操作歸根結底都是由客戶端來完成的,那麼客戶端必須得有如下的功能模塊:
服務端必須得有的功能模塊:
那麼,整體的通信流程就是如下的步驟:
首先是通信的 aidl 介面定義
然後是客戶端的連接操作與斷開連接操作,包括廣播接收者的注冊以及回調介面的實現
然後是客戶端的拉取數據和推送數據操作
接著是服務端的 iBinder 介面的實現,完成回調介面的注冊、業務子線程的開啟和關閉、數據的推送和數據的拉取操作
然後是服務端的主動連接和主動斷開連接操作
最後是服務端的 onUnbind 方法的實現,對回調介面進行反注冊
服務端模仿 FloatViewPlugin 自定義插件,實現 IServicePlugin 介面,定製個性化的懸浮窗插件
客戶端在 Appliaction 的 onCreate方法中初始化
在 MainActivity 上實現連接、斷開、數據通信
❸ android進階-AIDL之介面注冊/解注冊
AIDL-基本使用
AIDL-自定義數據類型
AIDL-修飾符in,out,inout
AIDL-重連方法
AIDL-介面注冊/解注冊
AIDL-連接池
為什麼要特意講解一下介面的注冊與取消注冊呢,因為在使用AIDL進程跨進程通信的時候, 每次傳遞的介面對象在內存中的地址都是不一樣的 ,所以在注冊了之後,無法使用常規的方式去取消, 因為注冊和解注冊傳遞的介面地址都不一樣 ,系統無法識別
由於上面的問題,AIDL中提供了一個專門解決上述情況的類 RemoteCallbackList ,其工作原理就是:
首先,在前面講解 AIDL的基本使用 的基礎上先增加新的AIDL介面以及注冊和解注冊方法:
然後就是 RemoteCallbackList 的使用方法了:
注冊/解注冊很簡單
接著是使用介面的方式:
ps: 需要注意的是 beginBroadcast() 方法和 finishBroadcast() 方法 必須配合使用 ,哪怕只是簡單的獲取集合大小
使用AIDL進行跨進程間通信中,往往我們是需要注冊監聽,讓服務端通知的,但是服務端也必須提供解注冊的方法,不然客戶端如果離開某個界面不想再接受消息了,雖然直接離開不做處理客戶端這邊不會出錯,但是服務端那邊的監聽集合還存在之前的,那麼就會浪費系統資源,所以有注冊監聽的時候,最好也要實現解注冊的方法
https://github.com/returntolife455/DemoList
《Android開發藝術探索》