Android跨進程通信AIDL服務
服務(Service)是android系統中非常重要的組件。Service可以脫離應用程序運行。也就是說,應用程序只起到一個啟動Service的作用。一但Service被啟動,就算應用程序關閉,Service仍然會在後臺運行。
android系統中的Service主要有兩個作用:後臺運行和跨進程通訊。後臺運行就不用說了,當Service啟動後,就可以在Service對象中 運行相應的業務代碼,而這一切用戶並不會察覺。而跨進程通訊是這一節的主題。如果想讓應用程序可以跨進程通訊,就要使用我們這節講的AIDL服 務,AIDL的全稱是Android Interface Definition Language,也就是說,AIDL實際上是一種接口定義語言。通過這種語言定義接口後,Eclipse插件(ODT)會自動生成相應的Java代碼接 口代碼。下面來看一下編寫一個AIDL服務的基本步驟。
1.在Eclipse工程的package目錄中建立一個擴展名為aidl的文件。package目錄就是Java類所在的目錄。該文件的語法類似於Java代碼。aidl文件中定義的是AIDL服務的接口。這個接口需要在調用AIDL服務的程序中訪問。
2.如果aidl文件的內容是正確的,Eclipse插件會自動生成一個Java接口文件(*.java)。
3.建立一個服務類(Service的子類)。
4.實現由aidl文件生成的Java接口。
5.在AndroidManifest.xml文件中配置AIDL服務,尤其要註意的是,<action>標簽的android:name屬性值就是客戶端要引用該服務的ID,也就是Intent類構造方法的參數值。
現在我們來編寫一個AIDL服務,首先建立一個android工程:aidlservice。在aidlservice工程中有一個Main類,在Main類所有的目錄建立一個IMyService.aidl文件,內容如下:
package net.blogjava.mobile.aidlservice; interface IMyService { String getValue(); // 為AIDL服務的接口方法,調用AIDL服務的程序需要調用該方法 }
在保存IMyService.aidl文件後,ODT會在gen目錄下產生一個IMyService.java文件,讀者可以不必管這個文件中的內容,也 不需要修改該文件的內容。這個文件是由ODT自動維護的,只要修改了IMyService.aidl文件的內容,IMyService.java文件的內 容就會隨之改變。
然後建立一個MyService類,該類是Service的子類,代碼如下:
public class MyService extends Service { //IMyService.Stub類是根據IMyService.aidl文件生成的類,該類中包含了接口方法(getValue) public class MyServiceImpl extends IMyService.Stub { @Override public String getValue() throws RemoteException { return "從AIDL服務獲得的值."; } } @Override public IBinder onBind(Intent intent) { //該方法必須返回MyServiceImpl類的對象實例 return new MyServiceImpl(); } }
最後需要在AndroidManifest.xml文件中配置MyService類,代碼如下:
<!-- 註冊服務 --> <service android:name=".MyService"> <intent-filter> <!-- 指定調用AIDL服務的ID --> <action android:name="net.blogjava.mobile.aidlservice.IMyService" /> </intent-filter> </service>
下面來看看如何調用這個AIDL服務。首先建立一個android工程:aidlclient。然後將aidlservice工程中自動生成的 IMyService.java文件復制到aidlclient工程中。在調用AIDL服務之前需要先使用bindService方法綁定AIDL服務。 bindService方法需要一個ServiceConnection對象。ServiceConnection有一個 onServiceConnected方法,當成功綁定AIDL服務且,該方法被調用。並通過service參數返回AIDL服務對象。下面是調用 AIDL服務的完成代碼。
public class Main extends Activity implements OnClickListener { private IMyService myService = null; // 創建ServiceConnection對象 private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 獲得AIDL服務對象 myService = IMyService.Stub.asInterface(service); try { // 調用AIDL服務對象中的getValue方法,並以對話框中顯示該方法的返回值 new AlertDialog.Builder(Main.this).setMessage(myService.getValue()).setPositiveButton("確定", null).show(); } catch (Exception e) { } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override public void onClick(View view) { // 綁定AIDL服務 bindService(new Intent("net.blogjava.mobile.aidlservice.IMyService"), serviceConnection, Context.BIND_AUTO_CREATE); } }
在編寫AIDL服務和客戶端時要註意如下兩點:
1. AIDL服務中的onBind方法必須返回AIDL接口對象(MyServiceImpl對象)。該對象也是onServiceConnected事件方法的第2個參數值。
2. bindService方法的第1個參數是Intent對象,該對象構造方法的參數需要指定AIDL服務的ID,也就是在 AndroidManifest.xml文件中<service>標簽的<action>子標簽的android:name屬性 的值。
現在先運行aidlservice程序,以便安裝AIDL服務,然後運行aidlclient程序,並單擊按鈕,會顯示如圖11所示的對話框。對話框中的信息就是AIDL服務接口中getValue方法的返回值。
Android跨進程通信AIDL服務