AIDL:Android Interface Definition Language,即Android接口定义语言.
Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。
与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。
Android应用程序组件中的(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个重要的组件Service同样可以。
因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
1、aidl文件,一般是以I开头来命名
ICallback.aidl, 这里定义好了一个interface,dispatchMessage().
package com.android.demo.aidl;
import android.os.Bundle;
oneway interface ICallback {
void dispatchMessage(int what, in Bundle value);
}
IRemoteService.aidl,这里写好了两个Interface接口
package com.android.demo.aidl;
import com.android.demo.aidl.ICallback;
interface IRemoteService {
void registerCallBack(ICallback cb);
void sendMessageToRemoteService(int what, in Bundle bundle);
}
2、当写好一个aidl文件后,需要写一个对应继承Binder对象的类
CallBack.java,可以看到这里是继承ICallback.Stub。同时实现ICallback.aidl写好的接口dispatchMessage()
package com.android.client.demo;
import android.os.Bundle;
import android.os.RemoteException;
import com.android.demo.aidl.ICallback;
public class CallBack extends ICallback.Stub {
private final String TAG = "CallBack";
@Override
public void dispatchMessage(int what, Bundle value) throws RemoteException {
XLog.i(TAG, "dispatchMessage() what = " + what);
}
}
RemoteService.java,这个是继承IRemoteService.stub。同时需要实现在IRemotesercive.aidl写好的接口。
package com.android.service.demo;
import android.os.Bundle;
import android.os.RemoteException;
import com.android.demo.aidl.ICallback;
import com.android.demo.aidl.IRemoteService;
public class RemoteService extends IRemoteService.Stub {
private final String TAG = "RemoteService";
private ICallback mICallback = null;
public static final int MSG_DEFAULT = 1;
public static final int MSG_START_DOWNLOAD = MSG_DEFAULT + 1;
public static final int MSG_STOP_DOWNLOAD = MSG_DEFAULT + 2;
public static final int MSG_DOWNLOAD_SUCCESS = MSG_DEFAULT + 3;
public static final int MSG_STOP_SUCCESS = MSG_DEFAULT + 4;
public RemoteService() {
XLog.i(TAG, "RemoteService()");
}
@Override
public void sendMessageToRemoteService(int what, Bundle bundle) throws RemoteException {
XLog.i(TAG, "sendMessageToRemoteService() what = " + what);
switch (what) {
case MSG_START_DOWNLOAD: {
//here service to do something
if (mICallback != null) {
XLog.i(TAG, "send download success message to client");
mICallback.dispatchMessage(MSG_DOWNLOAD_SUCCESS, null);
}
return;
}
case MSG_STOP_DOWNLOAD: {
if (mICallback != null) {
XLog.i(TAG, "send stop success message to client");
mICallback.dispatchMessage(MSG_STOP_SUCCESS, null);
}
return;
}
default:
break;
}
}
@Override
public void registerCallBack(ICallback cb) throws RemoteException {
XLog.i(TAG, "registerCallBack()");
mICallback = cb;
}
}
3、当Service被绑定的时候,返回一个继承binder接口的对象,即RemoteService对象
@Override
public IBinder onBind(Intent intent) {
XLog.i(TAG, "onBind() ");
mRemoteService = new RemoteService();
return mRemoteService;
}
4、绑定Service的Activity里面,在bindService的地方,需要一个ServiceConnection的变量。对应的onServiceConnected()返回的参数里面可以获取到对应的Ibinder对象
private void bindBGService() {
XLog.i(TAG, "bindBGService()");
Intent service = new Intent(Util.START_BGSERVIVE_ACTION);
bindService(service, mConnection, Context.BIND_AUTO_CREATE);
}
private IRemoteService mRemoteService = null;
private ICallback mCallBack = null;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
XLog.i(TAG, "onServiceConnected()");
mRemoteService = (IRemoteService) IRemoteService.Stub.asInterface(service);
mCallBack =new CallBack();
try {
mRemoteService.registerCallBack(mCallBack);
mRemoteService.sendMessageToRemoteService(Util.MSG_START_DOWNLOAD, null);
} catch (RemoteException e) {
XLog.i(TAG, "send start download msg fail! ");
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
XLog.i(TAG, "onServiceDisconnected()");
mRemoteService = null;
}
};
5、应用Activity里面,通过binder对象直接使用AIDL定义好的接口。
当我们获取到 IRemoteService 对象后,我们就可以直接调用服务器端RemoteService的接口了。不同进程之间的通信机制就建立起来了。
不同应用,只需分别导入相同的AIDL文件,即约定好的接口。然后分别实现对应的功能,进程之间的通信就建立起来。
mRemoteService = (IRemoteService) IRemoteService.Stub.asInterface(service);
mCallBack =new CallBack();
try {
mRemoteService.registerCallBack(mCallBack);
mRemoteService.sendMessageToRemoteService(Util.MSG_START_DOWNLOAD, null);
} catch (RemoteException e) {
XLog.i(TAG, "send start download msg fail! ");
e.printStackTrace();
}
附件: Demo source Code