1. 程式人生 > >Android跨進程通信AIDL服務

Android跨進程通信AIDL服務

客戶端 onclick 所有 lte ons 目錄 www main 客戶

服務(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服務