1、什么是aidl
Aidl 全称Android Interface Definition Language,Android接口定义语言,用于定义进程之间通信协议。
2、进程通信
Android中系统提供了很多服务,例如AlarmManager,NotificationManager等,这些服务都在system server进程中,Android中应用有自己的进程,如下图:application所在进获取服务时需要跟system server进程进程通信。
当应用想要获取AlarmManger服务时可以通过:
val alarmManager=context.getSystemService(ALARM_SERVICE)
如下图,通过context.getSystemService(ALARM_SERVICE)获取alarmManager服务,其实是从system service进程中获取服务,system service 进程中会使用SystemServiceRegistry来注册服务。
在SystemServiceRegistry中有静态代码块如下会进行service的注册:
private static <T> void registerService(@NonNull String serviceName,
@NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
SYSTEM_SERVICE_CLASS_NAMES.put(serviceName, serviceClass.getSimpleName());
}
3、IPC
ipc全称Inter-Process Communication,进程通信,在Android中使用binder进行ipc通信,application与system server是两个不同的进程,在application中要获取system service 中的manager服务,需要使用binder进行进程通信如下:
在manager和service中间其实还有添加了一个proxy代理类和stub,这样manager只需要跟proxy交互,具体的通信逻辑交给proxy,在system server中也是提供了一个stub类。
4、AIDL
由上面可知应用进程和系统进程的通信方法,aidl就是用来定义通信协议的,在下图中框出来部分就属于aidl。
具体到AlarmManager中如下:
5、AIDL使用
在main目录下创建一个aidl目录,然后在aidl目录下新建一个aidl文件:
默认文件名为IMyAidlInterface.aidl,在IMyAidlInterface中定义所需要的方法
interface IMyAidlInterface {
String getMessage();
}
创建完成IMyAidlInterface后,选择rebuild项目,Android studio会在build/generated/aidl_source_output_dir下自动生成IMyAidlInterface的java类
这个类中生成一个stub类和一个proxy的内部类,如下:
stub类
public static abstract class Stub extends android.os.Binder implements com.example.aidld.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.example.aidld.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.example.aidld.IMyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.example.aidld.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.aidld.IMyAidlInterface))) {
return ((com.example.aidld.IMyAidlInterface)iin);
}
return new com.example.aidld.IMyAidlInterface.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
java.lang.String descriptor = DESCRIPTOR;
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(descriptor);
return true;
}
case TRANSACTION_getMessage:
{
data.enforceInterface(descriptor);
java.lang.String _result = this.getMessage();
reply.writeNoException();
reply.writeString(_result);
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
}
proxy类
private static class Proxy implements com.example.aidld.IMyAidlInterface
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/ // void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
// double aDouble, String aString);
@Override public java.lang.String getMessage() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
boolean _status = mRemote.transact(Stub.TRANSACTION_getMessage, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getMessage();
}
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static com.example.aidld.IMyAidlInterface sDefaultImpl;
}
创建stub实现类
public class MyImplementor extends IMyAidlInterface.Stub {
@Override
public String getMessage() {
return "hello world this good";
}
}
创建BoundService
class BoundService : Service() {
private val TAG: String = "BoundService"
private var binder: Binder = MyImplementor()
override fun onBind(intent: Intent?): IBinder {
return binder
}
}
在activity中获取service的binder数据
private var aidlInterface: IMyAidlInterface? = null
private fun createConnect() {
connect = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
//connect
aidlInterface = IMyAidlInterface.Stub.asInterface(service)
Log.d(TAG, "onServiceConnected ${aidlInterface?.message}")
slogin.text = aidlInterface?.message
}
override fun onServiceDisconnected(name: ComponentName?) {
//disconnect
Log.d(TAG, "onServiceDisconnected")
aidlInterface = null
}
}
}
由上可以看到IBinder转换调用了 IMyAidlInterface.Stub.asInterface(service)其中Stub的asInterface调用了Proxy的方法如下:
public static com.example.aidld.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.aidld.IMyAidlInterface))) {
return ((com.example.aidld.IMyAidlInterface)iin);
}
return new com.example.aidld.IMyAidlInterface.Stub.Proxy(obj);
}