天天看點

IPC—AIDL最簡單的實作步驟

1.什麼是AIDL?

AIDL : Android Interface Definition Language 縮寫, 即Android接口定義語言。

2.使用AIDL有什麼好處?

Android系統中的程序之間不能共享記憶體,是以,需要提供一些機制在不同程序之間進行資料通信。

為了使其他的應用程式也可以通路本應用程式提供的服務,Android系統采用了遠端過程調用(Remote Procedure Call,RPC)方式來實作。與很多其他的基于RPC的解決方案一樣,Android使用一種接口定義語言(Interface Definition Language,IDL)來公開服務的接口。我們知道4個Android應用程式元件中的3個(Activity、BroadcastReceiver和ContentProvider)都可以進行跨程序通路,另外一個Android應用程式元件Service同樣可以。是以,可以将這種可以跨程序通路的服務稱為AIDL(Android Interface Definition Language)服務。

3.選擇AIDL的使用場合

官方文檔特别提醒我們何時使用AIDL是必要的:隻有你允許用戶端從不同的應用程式為了程序間的通信而去通路你的service,以及想在你的service處理多線程。

下面是使用AIDL服務的步驟:

(1)在Eclipse Android工程的Java包目錄中建立一個擴充名為aidl的檔案。 該檔案的文法類 似于Java代碼,但會稍有不同。 (2)如果aidl檔案的内容是正确的,ADT會自動生成一個Java接口檔案(*.java)。

(3)建立一個服務類(Service的子類)。

(4)實作由aidl檔案生成的Java接口。

(5)在AndroidManifest.xml檔案中配置AIDL服務,尤其要注意的是,<action>标簽中android:name的屬性值就是用戶端要引用該服務的ID,也就是Intent類的參數值。

詳細步驟如下:

第一步我們在Eclipse Android工程的Java包目錄中建立一個擴充名為.aidl的檔案ICat.aidl,如圖1:

IPC—AIDL最簡單的實作步驟

接着我們再編寫一下ICat.aidl裡面的内容,注意這裡的接口規範和我們java裡面的接口規範是有差別的,具體的規範這裡省略。

IPC—AIDL最簡單的實作步驟

這裡的 ICat.aidl 檔案編寫完 Ctrl + S 儲存後,ADT會自動生成一個Java接口檔案(*.java)。如圖:

IPC—AIDL最簡單的實作步驟

下面我們在來建立一個Service的子類AidlService,實作由aidl檔案生成的Java接口代碼如下:

package org.crazyit.service;

import java.util.Timer;
import java.util.TimerTask;

import org.crazyit.service.ICat.Stub;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;


public class AidlService extends Service
{
	private CatBinder catBinder;
	Timer timer = new Timer();
	String[] colors = new String[]{
		"紅色",
		"黃色",
		"黑色"
	};
	double[] weights = new double[]{
		2.3,
		3.1,
		1.58
	};
	private String color;
	private double weight;
	// 繼承Stub,也就是實作額ICat接口,并實作了IBinder接口
	public class CatBinder extends Stub
	{
		@Override
		public String getColor() throws RemoteException
		{
			return color;
		}
		@Override
		public double getWeight() throws RemoteException
		{
			return weight;
		}
	}
	@Override
	public void onCreate()
	{
		super.onCreate();
		catBinder = new CatBinder();
		timer.schedule(new TimerTask()
		{
			@Override
			public void run()
			{
				// 随機地改變Service元件内color、weight屬性的值。
				int rand = (int)(Math.random() * 3);
				color = colors[rand];
				weight = weights[rand];
				System.out.println("--------" + rand);
			}
		} , 0 , 800);
	}
	@Override
	public IBinder onBind(Intent arg0)
	{
		/* 傳回catBinder對象
		 * 在綁定本地Service的情況下,該catBinder對象會直接
		 * 傳給用戶端的ServiceConnection對象
		 * 的onServiceConnected方法的第二個參數;
		 * 在綁定遠端Service的情況下,隻将catBinder對象的代理
		 * 傳給用戶端的ServiceConnection對象
		 * 的onServiceConnected方法的第二個參數;
		 */
		return catBinder; //①
	}
	
	@Override
	public void onDestroy()
	{
		timer.cancel();
	}
}
           

到上面為止服務端的代碼完成了,最後一步别忘記了,在AndroidManifest.xml檔案中配置AIDL服務, 尤其要注意的是, <action> 标簽中 android:name 的屬性值就是用戶端要引用該服務的ID,也就是Intent類的參數值。如圖所示:

IPC—AIDL最簡單的實作步驟

到此為止,伺服器端的代碼已經完成了。現在我們在來完成用戶端如何調用服務端定義的接口方法實作,具體步驟如下: 1.同樣我們需要編寫和服務端務必是一樣的.aidl檔案,這裡我們直接複制服務端的ICat.aidl檔案到用戶端工程org.crazyit.service包下,這裡注意包名必須要和伺服器端的保持一緻!如圖所示:

IPC—AIDL最簡單的實作步驟

最後一步我們編寫一個AidlClient類用戶端代碼就OK了!

<pre name="code" class="java">package org.crazyit.client;

import org.crazyit.service.ICat;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

/**
 * 
 * @author zhiwei.yin
 * 2016-3-4
 * 說明:用戶端AIDL服務的調用
 */
public class AidlClient extends Activity
{
	private ICat catService;
	private Button get;
	EditText color, weight;
	private ServiceConnection conn = new ServiceConnection()
	{
		@Override
		public void onServiceConnected(ComponentName name
			, IBinder service)
		{
			// 擷取遠端Service的onBind方法傳回的對象的代理
			catService = ICat.Stub.asInterface(service);
		}

		@Override
		public void onServiceDisconnected(ComponentName name)
		{
			catService = null;
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		get = (Button) findViewById(R.id.get);
		color = (EditText) findViewById(R.id.color);
		weight = (EditText) findViewById(R.id.weight);
		// 建立所需綁定的Service的Intent
		Intent intent = new Intent();
		intent.setAction("org.crazyit.aidl.action.AIDL_SERVICE");
		// 綁定遠端Service
		bindService(intent, conn, Service.BIND_AUTO_CREATE);
		get.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				try
				{
					// 擷取、并顯示遠端Service的狀态
					color.setText(catService.getColor());
					weight.setText(catService.getWeight() + "");
				}
				catch (RemoteException e)
				{
					e.printStackTrace();
				}
			}
		});
	}

	@Override
	public void onDestroy()
	{
		super.onDestroy();
		// 解除綁定
		this.unbindService(conn);
	}
}
           

到此為止,AIDL服務的步驟介紹完畢! 源碼示例下載下傳位址: http://download.csdn.net/detail/yinzhiwei2014/9452575