Android之AIDL服务
AIDL服務(wù)
?????? 服務(wù)(Service)是android系統(tǒng)中非常重要的組件。Service可以脫離應(yīng)用程序運(yùn)行。也就是說(shuō),應(yīng)用程序只起到一個(gè)啟動(dòng)Service的作用。一但Service被啟動(dòng),就算應(yīng)用程序關(guān)閉,Service仍然會(huì)在后臺(tái)運(yùn)行。?????? android系統(tǒng)中的Service主要有兩個(gè)作用:后臺(tái)運(yùn)行和跨進(jìn)程通訊。后臺(tái)運(yùn)行就不用說(shuō)了,當(dāng)Service啟動(dòng)后,就可以在Service對(duì)象中 運(yùn)行相應(yīng)的業(yè)務(wù)代碼,而這一切用戶(hù)并不會(huì)察覺(jué)。而跨進(jìn)程通訊是這一節(jié)的主題。如果想讓?xiě)?yīng)用程序可以跨進(jìn)程通訊,就要使用我們這節(jié)講的AIDL服 務(wù),AIDL的全稱(chēng)是Android Interface Definition Language,也就是說(shuō),AIDL實(shí)際上是一種接口定義語(yǔ)言。通過(guò)這種語(yǔ)言定義接口后,Eclipse插件(ODT)會(huì)自動(dòng)生成相應(yīng)的Java代碼接 口代碼。下面來(lái)看一下編寫(xiě)一個(gè)AIDL服務(wù)的基本步驟。
1.? 在Eclipse工程的package目錄中建立一個(gè)擴(kuò)展名為aidl的文件。package目錄就是Java類(lèi)所在的目錄。該文件的語(yǔ)法類(lèi)似于Java代碼。aidl文件中定義的是AIDL服務(wù)的接口。這個(gè)接口需要在調(diào)用AIDL服務(wù)的程序中訪(fǎng)問(wèn)。
2.? 如果aidl文件的內(nèi)容是正確的,Eclipse插件會(huì)自動(dòng)生成一個(gè)Java接口文件(*.java)。
3.? 建立一個(gè)服務(wù)類(lèi)(Service的子類(lèi))。
4.? 實(shí)現(xiàn)由aidl文件生成的Java接口。
5.? 在AndroidManifest.xml文件中配置AIDL服務(wù),尤其要注意的是,<action>標(biāo)簽的android:name屬性值就是客戶(hù)端要引用該服務(wù)的ID,也就是Intent類(lèi)構(gòu)造方法的參數(shù)值。
????? 現(xiàn)在我們來(lái)編寫(xiě)一個(gè)AIDL服務(wù),首先建立一個(gè)android工程:aidlservice。在aidlservice工程中有一個(gè)Main類(lèi),在Main類(lèi)所有的目錄建立一個(gè)IMyService.aidl文件,內(nèi)容如下:
package net.blogjava.mobile.aidlservice; interface IMyService { String getValue(); // 為AIDL服務(wù)的接口方法,調(diào)用AIDL服務(wù)的程序需要調(diào)用該方法 } package net.blogjava.mobile.aidlservice; interface IMyService { String getValue(); // 為AIDL服務(wù)的接口方法,調(diào)用AIDL服務(wù)的程序需要調(diào)用該方法 } 在保存IMyService.aidl文件后,ODT會(huì)在gen目錄下產(chǎn)生一個(gè)IMyService.java文件,讀者可以不必管這個(gè)文件中的內(nèi)容,也 不需要修改該文件的內(nèi)容。這個(gè)文件是由ODT自動(dòng)維護(hù)的,只要修改了IMyService.aidl文件的內(nèi)容,IMyService.java文件的內(nèi) 容就會(huì)隨之改變。
??????? 然后建立一個(gè)MyService類(lèi),該類(lèi)是Service的子類(lèi),代碼如下:
package net.blogjava.mobile.aidlservice; ... ... public class MyService extends Service { // IMyService.Stub類(lèi)是根據(jù)IMyService.aidl文件生成的類(lèi),該類(lèi)中包含了接口方法(getValue) public class MyServiceImpl extends IMyService.Stub { @Override public String getValue() throws RemoteException { return "從AIDL服務(wù)獲得的值." ; } } @Override public IBinder onBind(Intent intent) { // 該方法必須返回MyServiceImpl類(lèi)的對(duì)象實(shí)例 return new MyServiceImpl(); } } package net.blogjava.mobile.aidlservice; ... ... public class MyService extends Service { // IMyService.Stub類(lèi)是根據(jù)IMyService.aidl文件生成的類(lèi),該類(lèi)中包含了接口方法(getValue) public class MyServiceImpl extends IMyService.Stub { @Override public String getValue() throws RemoteException { return "從AIDL服務(wù)獲得的值."; } } @Override public IBinder onBind(Intent intent) { // 該方法必須返回MyServiceImpl類(lèi)的對(duì)象實(shí)例 return new MyServiceImpl(); } } 最后需要在AndroidManifest.xml文件中配置MyService類(lèi),代碼如下:<!-- 注冊(cè)服務(wù) --> <service android:name=".MyService" > <intent-filter> <!-- 指定調(diào)用AIDL服務(wù)的ID --> <action android:name="net.blogjava.mobile.aidlservice.IMyService" /> </intent-filter> </service>
<!-- 注冊(cè)服務(wù) --> <service android:name=".MyService"> <intent-filter> <!-- 指定調(diào)用AIDL服務(wù)的ID --> <action android:name="net.blogjava.mobile.aidlservice.IMyService" /> </intent-filter> </service> 下面來(lái)看看如何調(diào)用這個(gè)AIDL服務(wù)。首先建立一個(gè)android工程:aidlclient。然后將aidlservice工程中自動(dòng)生成的 IMyService.java文件復(fù)制到aidlclient工程中。在調(diào)用AIDL服務(wù)之前需要先使用bindService方法綁定AIDL服務(wù)。 bindService方法需要一個(gè)ServiceConnection對(duì)象。ServiceConnection有一個(gè) onServiceConnected方法,當(dāng)成功綁定AIDL服務(wù)且,該方法被調(diào)用。并通過(guò)service參數(shù)返回AIDL服務(wù)對(duì)象。下面是調(diào)用 AIDL服務(wù)的完成代碼。
package net.blogjava.mobile.aidlclient; ... ... public class Main extends Activity implements OnClickListener { private IMyService myService = null ; // 創(chuàng)建ServiceConnection對(duì)象 private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 獲得AIDL服務(wù)對(duì)象 myService = IMyService.Stub.asInterface(service); try { // 調(diào)用AIDL服務(wù)對(duì)象中的getValue方法,并以對(duì)話(huà)框中顯示該方法的返回值 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服務(wù) 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; // 創(chuàng)建ServiceConnection對(duì)象 private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 獲得AIDL服務(wù)對(duì)象 myService = IMyService.Stub.asInterface(service); try { // 調(diào)用AIDL服務(wù)對(duì)象中的getValue方法,并以對(duì)話(huà)框中顯示該方法的返回值 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服務(wù) bindService(new Intent("net.blogjava.mobile.aidlservice.IMyService"), serviceConnection, Context.BIND_AUTO_CREATE); } ... ... }
在編寫(xiě)AIDL服務(wù)和客戶(hù)端時(shí)要注意如下兩點(diǎn):
1.? AIDL服務(wù)中的onBind方法必須返回AIDL接口對(duì)象(MyServiceImpl對(duì)象)。該對(duì)象也是onServiceConnected事件方法的第2個(gè)參數(shù)值。
2.? bindService方法的第1個(gè)參數(shù)是Intent對(duì)象,該對(duì)象構(gòu)造方法的參數(shù)需要指定AIDL服務(wù)的ID,也就是在 AndroidManifest.xml文件中<service>標(biāo)簽的<action>子標(biāo)簽的android:name屬性 的值。
?現(xiàn)在先運(yùn)行aidlservice程序,以便安裝AIDL服務(wù),然后運(yùn)行aidlclient程序,并單擊按鈕,會(huì)顯示如圖11所示的對(duì)話(huà)框。對(duì)話(huà)框中的信息就是AIDL服務(wù)接口中g(shù)etValue方法的返回值。
總結(jié)?
????? 本文介紹了4種跨進(jìn)程通訊的方式:Activity、ContentProvider、Broadcast和AIDL Service。其中Activity可以跨進(jìn)程調(diào)用其他應(yīng)用程序的Activity;ContentProvider可以訪(fǎng)問(wèn)其他應(yīng)用程序返回的 Cursor對(duì)象;Broadcast采用的是被動(dòng)接收的方法,也就是說(shuō),客戶(hù)端只能接收廣播數(shù)據(jù),而不能向發(fā)送廣播的程序發(fā)送信息。AIDL Service可以將程序中的某個(gè)接口公開(kāi),這樣在其他的應(yīng)用程序中就可以象訪(fǎng)問(wèn)本地對(duì)象一樣訪(fǎng)問(wèn)AIDL服務(wù)對(duì)象了。這4種跨進(jìn)程通訊的方式可以應(yīng)用在 不同的場(chǎng)合,例如,在需要顯示可視化的界面時(shí)可以用Activity,需要返回記錄集時(shí)可以用ContentProvider。至于在應(yīng)用程序中具體要用 到哪一種或幾種方式進(jìn)行跨進(jìn)程通訊,讀者可以根據(jù)實(shí)際情況進(jìn)行選擇。
總結(jié)
以上是生活随笔為你收集整理的Android之AIDL服务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 探讨float类型的数值,为什么两个fl
- 下一篇: sqlite数据库的char,varch