Android之AIDL服务
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服務的程序需要調用該方法 } package net.blogjava.mobile.aidlservice; interface IMyService { String getValue(); // 為AIDL服務的接口方法,調用AIDL服務的程序需要調用該方法 } 在保存IMyService.aidl文件后,ODT會在gen目錄下產生一個IMyService.java文件,讀者可以不必管這個文件中的內容,也 不需要修改該文件的內容。這個文件是由ODT自動維護的,只要修改了IMyService.aidl文件的內容,IMyService.java文件的內 容就會隨之改變。
??????? 然后建立一個MyService類,該類是Service的子類,代碼如下:
package net.blogjava.mobile.aidlservice; ... ... 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(); } } package net.blogjava.mobile.aidlservice; ... ... 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>
<!-- 注冊服務 --> <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服務的完成代碼。
package net.blogjava.mobile.aidlclient; ... ... 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); } ... ... } package net.blogjava.mobile.aidlclient; ... ... 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方法的返回值。
總結?
????? 本文介紹了4種跨進程通訊的方式:Activity、ContentProvider、Broadcast和AIDL Service。其中Activity可以跨進程調用其他應用程序的Activity;ContentProvider可以訪問其他應用程序返回的 Cursor對象;Broadcast采用的是被動接收的方法,也就是說,客戶端只能接收廣播數據,而不能向發送廣播的程序發送信息。AIDL Service可以將程序中的某個接口公開,這樣在其他的應用程序中就可以象訪問本地對象一樣訪問AIDL服務對象了。這4種跨進程通訊的方式可以應用在 不同的場合,例如,在需要顯示可視化的界面時可以用Activity,需要返回記錄集時可以用ContentProvider。至于在應用程序中具體要用 到哪一種或幾種方式進行跨進程通訊,讀者可以根據實際情況進行選擇。
總結
以上是生活随笔為你收集整理的Android之AIDL服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 探讨float类型的数值,为什么两个fl
- 下一篇: Android Caused by: j