Android 系统中,各应用程序都运行在自己的进程中,进程之间一般无法直接进行数据交换。为了实现这种跨进程通信(interprocess communication,简称IPC),Android 提供了AIDL Service。
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