Android AIDL的實現

      AIDL (Android Interface Definition Language) 是一種IDL 語言,用於生成能夠在Android設備上兩個進程之間進行進程間通訊(interprocess communication, IPC)的代碼。若是在一個進程中(例如Activity)要調用另外一個進程中(例如Service)對象的操做,就可使用AIDL生成可序列化的參數。 java

【一】AIDL文件的建立:

     AIDL使用簡單的語法來聲明接口,描述其方法以及方法的參數和返回值。這些參數和返回值能夠是任何類型,甚至是其餘AIDL生成的接口。 android

     其中對於Java編程語言的基本數據類型 (int, long, char, boolean等),String和CharSequence,集合接口類型List和Map,不須要import 語句。 而若是須要在AIDL中使用其餘AIDL接口類型,須要import,即便是在相同包結構下。AIDL容許傳遞實現Parcelable接口的類,須要import. 
     須要特別注意的是, 對於非基本數據類型,也不是String和CharSequence類型的,須要有方向指示,包括in、out和inout,in表示由客戶端設置,out表示由服務端設置,inout是二者都可設置。

    AIDL只支持接口方法,不能公開static變量。 編程

    其中AIDL的方法還提供了oneway這個關鍵字,能夠用關鍵字oneway來標明遠程調用的行爲屬性,使用了該關鍵字,那麼遠程調用將僅僅是調用所需的數據傳輸過來並當即返回,而不會等待結果的返回,也便是說不會阻塞遠程線程的運行。AIDL接口將最終將得到一個從Binder線程池中產生的調用(和普通的遠程調用相似)。若是關鍵字oneway在本地調用中被使用,將不會對函數調用有任何影響。   app

    1.服務端接口的建立:

package com.liusl.aidl;
import com.liusl.aidl.AIDLCallback;
interface ServiceAIDL {
	void registerClient(AIDLCallback cb);
	void unregisterClient(AIDLCallback cb);
	int add(int i, int j);
	int sum(in int[] numbers);
}

    2.回調接口的建立:

package com.liusl.aidl;

interface AIDLCallback {

	int returnResult(int result);
}

【二】服務端接口的實現:

    將AIDLCallback做爲服務端給客戶端的回調,這樣才實現了服務端和客戶端的通訊。同時使服務端繼承service類,實現onBind方法,建立AIDLService對象,這樣才能將服務端的接口提供給客戶端進行調用。 編程語言

package com.liusl.aidl;

import com.liusl.aidl.AIDLCallback;
import com.liusl.aidl.ServiceAIDL;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class MyAIDLService extends Service {

	public final String TAG = "[service]";
	int sum = 0;

	@Override
	public IBinder onBind(Intent intent) {
		Log.i(TAG, "[MyAIDLService] onBind(intent)...");
		return (IBinder) new ServiceAIDLImpl();
	}

	class ServiceAIDLImpl extends ServiceAIDL.Stub {

		private AIDLCallback cb;

		@Override
		public void registerClient(AIDLCallback cb) throws RemoteException {		
			this.cb = cb;
			Log.i(TAG, "[ServiceAIDLImpl] registerClient start...");
			cb.asBinder().linkToDeath(new DeathRecipient() {
				 @Override
				public void binderDied() {
					try {
						Log.i(TAG, "[ServiceAIDLImpl]binderDied.");
					} catch (Throwable e) {
					}
				}
			}, 0);

			Log.i(TAG, "[ServiceAIDLImpl] registerClient end...");
		}

		@Override
		public void unregisterClient(AIDLCallback cb) throws RemoteException {

		}

		@Override
		public int add(int i, int j) throws RemoteException {
			sum = 0;
			sum = i + j;
			cb.returnResult(sum);
			return 0;
		}

		@Override
		public int sum(int[] numbers) throws RemoteException {
			sum = 0;
			for (int i = 0; i < numbers.length; i++) {
				sum += numbers[i];
			}
			cb.returnResult(sum);
			return 0;
		}

	}
}


【三】服務的建立及Activity的實現:

         在客戶端使用服務端的AIDL前,須要先經過建立一個客戶端與服務端的鏈接,步驟以下: ide

    1.建立intent:

        String actionName = "com.liusl.aidl.MyAIDLService"; 函數

        Intent intent = new Intent(actionName) this

    2.實現一個MyServiceConnection類,繼承ServiceConnection,重寫onServiceConnected和onServiceDisConnected方法。

    3.新建了BindService對象:

        MyServiceConnection connection = new MyServiceConnection(); spa

        經過調用bindService(intent, connection, Context.BIND_AUTO_CREATE);->onServiceConnected(),在OnServiceConnected()中獲取服務端得aidl對象, .net

        myservice = (ServiceAIDL) ServiceAIDL.Stub.asInterface(service);

    4.實現客戶端的AIDLCallback接口:

private class AIDLCallbackImpl extends AIDLCallback.Stub {

		public int returnResult(int result) {
    			textView.setText("Result :" + result);
			return result;
		}
	}

    5.經過服務端的aidl對象調用服務端的註冊方法以及其餘的方法:

    myservice.registerClient(callBack);

    myservice.add(2, 3);

    由此就完成了客戶端註冊一個客戶到服務端而且調用服務端的add方法,服務端將add的結果反饋給回調方法,客戶端在接收到回調傳來的值後進行顯示操做。

注意:須要在AndroidMainFest.xml中對服務進行註冊:

<service android:name="com.liusl.aidl.MyAIDLService">
       	<intent-filter>
        	<action android:name="com.liusl.aidl.MyAIDLService"/>
       	</intent-filter>
 </service>

代碼所在位置:

http://www.oschina.net/code/snippet_1051613_22116

相關文章
相關標籤/搜索