android之Service介紹之二 AIDL

首先描述下我們想要實現的內容,我們希望在一個應用中通過點擊按鈕,去操作另一個進程中應用的音樂播放功能。

如圖,我們點擊“播放”時,系統就會去遠程調用我們提供的一個service(與當前service不是同一個應用哦),然後操作service中的音樂播放,點擊“停止”則會終止播放。想要重新播放的話,必須先點“銷燬service”,再點播放按鈕哦。(至於這裏爲什麼要先點銷燬按鈕才能播放,完全是爲了給大家展示下,遠程調用service時,怎麼去解綁service)。

 

       在這個例子中,我們用到了一個非常重要的概念,AIDL。

AIDL(android interface definition language)android接口描述語言,其主要的作用就是允許我們在不同的進程間進行通信。

      我們都知道每個應用程序都運行在各自的進程中,並且android平臺是不允許不同進程間進行直接的對象數據等傳遞的。如果我們非要進行進程間的通訊,那麼我們就必須將我們的數據對象分解成一個個微小的、可以被操作系統理解的數據單元,然後有序的通過進程邊界的檢查。

      如果讓我們自己實現,那麼這個過程都愁死一批批的程序人了。幸好android,爲我們解決了這個問題,這就是AIDL出現的原因了。

      AIDL (Android Interface Definition Language)是一種IDL 語言,用於生成可以在Android設備上兩個進程之間進行進程間通信(IPC)的代碼。如果在一個進程中(例如Activity)要調用另一個進程中(例如Service)對象的操作,就可以使用AIDL生成可序列化的參數。
AIDL IPC機制是面向接口的,像COM或Corba一樣,但是更加輕量級。它是使用代理類在客戶端和實現端傳遞數據。

 

     注意:AIDL只支持方法,不能定義靜態成員,並且方法也不能有類似public等的修飾符;AIDL運行方法有任何類型的參數和返回值,在java的類型中,以下的類型使用時不需要導入包(import),基本數據類型、String、Map、List.當然爲了避免出錯,建議只要使用了,就導入包。

-------------------------------------------------------------------------------

使用AIDL的步驟:

 

服務端(提供服務):

第一步:定義一個*.aidl文件,該文件裏是符合aidl語言規範的接口定義,裏面定義了外部應用可以訪問的方法。當我們保存該文件的時候,eclipse會自動爲我們在gen文件夾下生成一個相應的java接口文件。例如RemoteServiceInterface.java

 

 第二步:定義一個自己的service,    並將其註冊到androidManifest.xml文件中,例如:

<service android:name="MyRemoteService">
  <intent-filter>
  <action  android:name="cn.com.chenzheng_java.remote"/>
  </intent-filter>
 </service>

注意這裏一定要提供一個intent-filter,我們的客戶端進程就是通過該action訪問到服務端進程的哦。

我們都知道,在實現自己的service時,爲了其他應用可以通過bindService來和我們的service進行交互,我們都要實現service中的onBind()方法,並且返回一個繼承了Binder的內部類;在這裏,eclipse自動爲我們生成的RemoteServiceInterface.java中有一個實現了Binder的內部類,RemoteServiceInterface.Stub。AIDL要求我們,在這裏不能再直接去實現Binder類了,而是去實現,AIDL提供給我們的Stub類。 實現stub類的同時,AIDL還要求我們同時實現我們在接口中定義的各種服務的具體實現。至此爲止,我們的服務端已經和我們的aidl文件綁定到一起了哦。

 

  客戶端:

 

第一步:客戶端要想使用該服務,肯定要先知道我們的服務在aidl文件中到底對外提供了什麼服務,對吧?所以,第一步,我們要做的就是,將aidl文件拷貝一份到客戶端的程序中(這裏一定要注意,包路徑要和服務端的保持一致哦,例如服務端爲cn.com.chenzheng_java.remote.a.aidl,那麼在客戶端這邊也應該是這個路徑)。

 

第二步:我們都知道,想要和service交互,我們要通過bindService方法,該方法中有一個ServiceConnection類型的參數。而我們的主要代碼便是在該接口的實現中。

 

第三步:在ServiceConnection實現類的onServiceConnected(ComponentName name, IBinder service)方法中通過類似remoteServiceInterface = RemoteServiceInterface.Stub.asInterface(service);方式就可以獲得遠程服務端提供的服務的實例,然後我們就可以通過remoteServiceInterface 對象調用接口中提供的方法進行交互了。(這裏的關鍵是通過*.Stub.asInterface(service);方法獲取一個aidl接口的實例哦)

 

我們前面在服務端中說過了,必須提供一個intent-filter來匹配請求是否合法,所以我們在客戶端訪問服務的時候,還必須傳遞包含了匹配action的Intent哦。

--------------------------------------------------------------------------------------

下邊整體是代碼:

 

 

 

 

 

 

 

 

 遠程服務端:

RemoteServiceInterface.aidl

MyRemoteService.java

RemoteServiceActivity.java

androidManifest.xml

客戶端:

activity代碼:

music.xml

其他沒有粘貼出來的代碼都是由系統默認生成的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章