AIDL (Android Interface Definition Language) 是一種IDL 語言,用於生成可以在Android 設備上兩個進程之間進行進程間通信(interprocess communication, IPC)的代碼。如果在一個進程中(例如Activity)要調用另一個進程中(例如Service)對象的操作,就可以使用AIDL生成可序列化的參數。
官方文檔特別提醒我們何時使用AIDL是必要的:只有你允許客戶端從不同的應用程序爲了進程間的通信而去訪問你的service,以及想在你的service處理多線程。
Android 的遠程Service 調用,需要先定義一個遠程調用的接口,然後爲該接口提供一個實現類。客戶端訪問Service 時,Android 並不是直接返回Service 對象給客戶端,只是將Service 的代理對象(IBinder 對象)通過onBind () 方法返回給客戶端,因此AIDL 遠程接口的實現類就是IBinder 實現類。與綁定本地Service 不同的是,本地Service 的onBind () 方法會直接把IBinder 對象本身傳給客戶端的ServiceConnection 的onServiceContected 方法的第二個參數。但是AIDL Service 的onBind () 方法只是把IBinder 對象的代理傳給客戶端的ServiceConnection 的onServiceContected 方法的第二個參數。
創建.aidl 文件
AIDL接口定義語言的語法十分簡單,這樣的接口定義語言並不是真正的編程語言,它只是定義兩個進程之間通信的接口:
AIDL 定義接口的源代碼必須以.aidl 結尾;
AIDL 接口中用到的書類型,除了基本類型、String、List、Map、CharSequence之外,其他類型全部需要導包,即使他們在同一個包中,也需要導包。
新建一個項目:AIDLService作爲服務器端
創建ICat.aidl文件
interface ICat
{
String getColor();
double getWeight();
}
定義好上面的AIDL接口之後,ADT工具自動在gen目錄下生成一個ICat.java接口,在該接口裏包含一個Stub內部類,該內部類實現了IBinder、ICat兩個接口,這個Stub類將會作爲遠程Service的回調類--它實現了IBinder接口,作爲service的onBind()方法的返回值。
定義一個Service實現類AidlService.java,該Service的onBind()方法所返回的IBinder對象應該是ADT所生成的ICat.Stub的子類的實例。
/**
*
*/
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;
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()
{
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();
}
}
在AndroidMainfest.xml中註冊該Service
<!-- 定義一個Service組件 -->
<service android:name=".AidlService">
<intent-filter>
<action android:name="org.crazyit.aidl.action.AIDL_SERVICE" />
</intent-filter>
</service>
新建客戶端項目AidlClent
第一步將服務端的AIDL接口文件複製到客戶端應用中,注意包名一致性
客戶端綁定遠程Service
1創建serviceConnection對象
2以ServiceConnection對象作爲參數,調用Context的bindService()方法綁定遠程Service即可
客戶端在綁定service時,通過ICat.Stub.asInterface(service) 返回一個代理對象,並通過該對象調用接口中定義的方法
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;
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)
{
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);
Intent intent = new Intent();
intent.setAction("org.crazyit.aidl.action.AIDL_SERVICE");
bindService(intent, conn, Service.BIND_AUTO_CREATE);
get.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
try
{
//״̬
color.setText(catService.getColor());
weight.setText(catService.getWeight() + "");
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
});
}
@Override
public void onDestroy()
{
super.onDestroy();
// �����
this.unbindService(conn);
}
}
主佈局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/get"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/get"
android:layout_gravity="center_horizontal"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/get"
/>
<EditText
android:id="@+id/color"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:editable="false"
android:focusable="false"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/get"
/>
<EditText
android:id="@+id/weight"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:editable="false"
android:focusable="false"
/>
</LinearLayout>
瘋狂Android講義第二版Aidl示例鏈接:http://pan.baidu.com/s/1qYQrULu 密碼:hgk3