您的位置:首页 > 移动开发 > Android开发

AIDL跨进程通信在Android的应用

2015-10-01 23:52 573 查看
一个Android应用程序就是一个进程,而Java并不支持跨进程的内存共享,所以在两个Android应用程序之间不能直接共享内存,那么两个Android应用程序之间要传递对象那该怎么解决呢?那么就需要一套不同进程间的通信机制。那么这是就可以用AIDL(Android Interface Definition language )了,它是一种IDL语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码,她能把对象解析成操作系统能够理解的数据格式,以达到跨界对象访问的目的。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

下面通过一个例子讲解一下AIDL的具体用法。
打开Android Studio新建一个工程,然后新建一个继承Service的服务类,在该类中的onBind方法中可以写条控制台输出语句,方便绑定服务时观察程序执行情况。在onCreate方法里写一个线程,让它每2s输出一条信息,及时观察数据的改变:

@Override
public void onCreate() {
super.onCreate();
System.out.println("start service");

new Thread() {
@Override
public void run() {
super.run();
runing = true;
while (runing){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(data);
}
}
}.start();

}


可以现在这个应用里面开启服务和关闭服务观察一下效果。
下面建立第二个应用,在该工作空间里新建一个module,我们需要在这个应用的Activity里面启动前面我们创建好的应用程序里的服务。在布局里面新建4个按钮,分别是:启动另一个进程的服务,暂停另一个进程的服务,绑定另一进程的服务,解除另一个进程的绑定,然后再增加一个EditText和Button,EditText用于获取用户输入的数据,Button用于同步两个进程的数据,也就是将数据从当前应用传统到另一个应用。两个工程建好了,下面就是解决两个进程间的数据通信,这时我们就要用AIDL机制了。
下面讲解AIDL机制的实现:
在上面建的第一个应用(也就是带service的那个)里面新建一个AIDL文件:


新建后再main目录下会出现一个aidl的文件夹,里面有一个文件类型为aidl的文件,然后在文件里面写个方法,用于接收数据。那另一个进程怎么把数据传输过来的呢?
首先我们在第二个应用程序里面通过bindService方法和第一个应用的服务绑定,这个大家都懂啥,这一点不牵涉到AIDL,不通过AIDL是可以实习一个应用启动或者绑定另一个应用的服务,只是布不能实现内存的共享,在执行bindService方法后,会执行第一个service类里面的onBind方法并需要返回一个IBinder对象,在Android开发中,绑定服务可以返回一个对象,那两个进程怎么实现对象传输呢?
我们需要在第二个应用里面也建一个aidl文件,而且文件包名必须和第一个的相同,建立好后将第一个aidl文件里面的文件拷贝到第二个,这样两个应用就有了相同的aidl。



然后我们将第一个服务类里面的onBind方法里返回这个对象:

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
System.out.println("onband service");
return new AppServiceRemoteBlander.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean,
float aFloat, double aDouble, String aString) throws RemoteException {

}

@Override
public void setData(String data) throws RemoteException {
AppService.this.data = data;
}
};
}

setData是在aidl里面自定义的方法,由于是接口,所以需要实现。然后再第二个应用的onServiceConnected里面获取这个对象,onServiceConnected会在绑定成功后自动调用。

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("band service success");
System.out.println(service);
binder = AppServiceRemoteBlander.Stub.asInterface(service);
}


binder = AppServiceRemoteBlander.Stub.asInterface(service);

这一句不能用强制类型转换成aidl的类型,毕竟两个应用的对象在不同的内存,所以用上面提供的方法转换。

现在获得了对象,就可以调用steData方法将EditText的文本传递过去了。到这里差不多就可以了,一个简单的AIDL应用就诞生了
需要注意的是:
第一点:观察控制台的输出时,是那个应用输出的就要却换到相应的应用,不然看不到对应的输出效果:



第二点:由于对象实在onBind放法里面返回的,所以必须执行绑定操作才有对象返回,不然不能进行数据的传输,点击同步数据时程序会挂掉的
第三点:android5.0及以后启动服务必须显示启动
工程下载地址:http://download.csdn.net/detail/tuoguang/9152267
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: