IPC之AIDL
简介
IPC机制:进程间通信(Inter Process Communication的缩写);进程具有独立的资源空间,Android系统为每个进程都分配一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,导致不同虚拟机中访问同一个对象,会产生多个不同的数据副本;所以不同的进程之间无法共享数据,需要IPC机制跨进程通讯,相互传递数据。
IPC方式:Bundle,共享文件,广播,ContentProvider,Messager,AIDL,Socket七种方式;主要介绍AIDL通信的数据传递,分为两种情况:1)Activity向远程Service传递数据;2)远程Service向Activity传递数据。
AIDL是Android Interface Definition Language的缩写,AnDroid接口定义语言,在了解AIDL之前需要先了解Service的用法和Android序列化;
如何书写AIDL文件
通过上图的方式,可以直接创建一个AIDL文件;可以根据自己的需求,定义方法
//Activity 向Service传递数据
interface IMyAidlInterface {
void set(String str);//传递数据
}
开启远程服务
在充分了解普通Service的用法之后,跨进程开启Service也就很简单,不太了解Service的用法可先阅读Service的常见用法分析;
1 定义一个类继承Service,并且在manifests加上android:process=":****"(android:process=":remote")新的进程
2 startService(),stopService();bindService(),unbindService和正常Service的调用一样;
bindService()方式开启远程Service,并且传递数据
Activity端:
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected");
try {
myAIDLServie = null;
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myAIDLServie = IMyAidlInterface.Stub.asInterface(service);
try {
myAIDLServie.set("远程传递数据");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
Service端
IMyAidlInterface.Stub iBinder = new IMyAidlInterface.Stub() {
@Override
public void set(String str) {
Log.d(TAG, str);
//todo 做操作
}
};
以上是Activity通过AIDL向远程Service传递数据;
远程Service如何Activity传递数据呢?
主要有两种方式:1:广播;2:AIDL回调
主要介绍AIDL回调向Activity传递数据
1:定义一个AIDL文件,并且要在IMyAidlInterface.aidl中加入注册和反注册方法;
//用于Service 通知 Activity 的回调
interface ITaskCallback {
void setData(int data);
}
IMyAidlInterface.aidl添加注册,反注册方法
//Activity 向Service传递数据
interface IMyAidlInterface {
void set(String str);
void registerCallback(ITaskCallback iTaskCallback);
void unregisterCallback(ITaskCallback iTaskCallback);
}
Activity端
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected");
try {
myAIDLServie.unregisterCallback(callback);
myAIDLServie = null;
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myAIDLServie = IMyAidlInterface.Stub.asInterface(service);
try {
myAIDLServie.registerCallback(callback);
myAIDLServie.set("远程传递数据");
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
//Service 传递过来的数据的回调
privateITaskCallback.Stubcallback=new
ITaskCallback.Stub() {
@Override
public voidsetData(intdata)throwsRemoteException
{
Log.d(TAG,"setData::"+
data);
}
};
Service端
/**
*一个容器,容纳的对象是一些接口,用于执行列表中对象的回调函数,主要用于服务调用activity函数,或者解释为服务端和客户端通信。
*线程同步 在Activity销毁时
会自动反注册
*/
privateRemoteCallbackList<ITaskCallback>mCallbacks=new
RemoteCallbackList<ITaskCallback>();
IMyAidlInterface.Stub iBinder = new IMyAidlInterface.Stub() {
@Override
public void set(String str) {
Log.d(TAG, str);
callback();
}
@Override
public void registerCallback(ITaskCallback iTaskCallback) throws RemoteException {
Log.d(TAG, "registerCallback");
if (iTaskCallback != null) {
mCallbacks.register(iTaskCallback);
}
}
@Override
public void unregisterCallback(ITaskCallback iTaskCallback) throws RemoteException {
if (iTaskCallback != null) {
mCallbacks.unregister(iTaskCallback);
}
}
}
private voidcallback() {
final intN =mCallbacks.beginBroadcast();
for(inti
= 0;i < N;i++) {
try{
mCallbacks.getBroadcastItem(i).setData(1);
}catch(RemoteException e) {
e.printStackTrace();
}
}
mCallbacks.finishBroadcast();
}
以上就是远程Service通过AIDL调用Activit的方法或者向Activity传递数据的方法;
如有问题,请多指教