天天看點

Android跨程序通路-Service跨程序通路(AIDL服務)

前言:

服務(Service)是Android四大元件之一,它可以脫離應用程式在背景運作,另服務也可以進行跨程序通訊。要想實作服務跨程序,就要用到AIDL服務,AIDL的全稱是Android Interface Definition Language,也就是說,AIDL實際上是一種接口定義語言。通過這種語言定義接口後,Eclipse插件(ODT)會自動生成相應的Java接口代碼。

一、建立AIDL服務

1、在Eclipse工程的package目錄下,建立一個擴充名為aidl的檔案,該檔案的文法類似于Java代碼。aidl檔案中定義的是AIDL服務的接口。這個接口需要在調用AIDL服務的程式中通路。該檔案編寫正确後,會在gen目錄下自動生成一個.java檔案。aidl檔案内容如下:

package com.sarnasea.aidl;
interface IMyService{

	/**
	 * 為AIDL服務的接口方法,調用AIDL服務的程式需要調用該方法
	 * @return {@link String}
	 */
    String getValue();
}
           

2、實作AIDL檔案生成的JAVA接口,示例代碼如下:

class MyServiceImpl extends IMyService.Stub{

	@Override
	public String getValue() throws RemoteException {
		
		return "從AIDL服務擷取的值";
	}
}
           

3、建立一個服務類,将接口暴露給用戶端調用。示例代碼如下:

/**
 * @class description 遠端服務供用戶端調用
 */
public class RemoteService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		
		return new MyServiceImpl();
	}
}
           

4、在AndroidManifest.xml檔案中申明服務,指定其Action。示例代碼如下:

<service android:name="com.sarnasea.aidl.RemoteService">
            <intent-filter>
                <action android:name="com.sarnasea.aidl.IMyService"/>
			</intent-filter>
        </service>
           

這樣,AIDL服務就建立完成了,接下來就要實作用戶端調用AIDL服務.....

二、調用AIDL服務

在新的應用中可以調用上面建立的AIDL服務。首先需要将之前在gen目錄下自動生成的IMyService.java檔案複制到新的目錄。然後在Activity中調用bindService方法綁定服務,示例代碼如下:

//點選遠端調用服務按鈕
		case R.id.invoke_remote_service_btn:
						
			Intent serviceIntent = new Intent();
			// 設定Intent Action 屬性
			serviceIntent.setAction("com.sarnasea.aidl.IMyService");
			// 綁定服務
			bindService(serviceIntent, serviceConn, Service.BIND_AUTO_CREATE);
			break;
           

其中綁定服務方法中參數serviceConn為ServiceConnection對象,當成功綁定AIDL服務,onServiceConnected方法被調用。并通過service參數傳回AIDL服務對象,然後便可對AIDL服務對象進行操作,示例代碼如下:

// 綁定服務連接配接監聽接口
		serviceConn = new ServiceConnection() {

			@Override
			public void onServiceDisconnected(ComponentName name) {

				Toast.makeText(MainActivity.this, "遠端服務綁定失敗",
						Toast.LENGTH_SHORT).show();
			}

			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {

				// 綁定成功
				IMyService myService = IMyService.Stub.asInterface(service);
				try {
					String value = myService.getValue();
					Toast.makeText(MainActivity.this, value, Toast.LENGTH_SHORT)
							.show();
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
		};
           

注意:

1.  AIDL服務中的onBind方法必須傳回AIDL接口對象(MyServiceImpl對象)。該對象也是onServiceConnected事件方法的第2個參數值。

2.  bindService方法的第1個參數是Intent對象,該對象構造方法的參數需要指定AIDL服務的ID,也就是在 AndroidManifest.xml檔案中<service>标簽的<action>子标簽的android:name屬性的值。