我们新建了AIDL文件后,再build一下项目,就会生成编译后的AIDL,如:

// IMyAidlInterface.aidl
package com.wong.remoteservice;
// Declare any non-default types here with import statements
interface IMyAidlInterface {

// 服务端数据
String getString();
}

编译后得到的 IMyAidlInterface.java:

/*
* This file is auto-generated. DO NOT MODIFY.
*/
package com.wong.remoteservice;
// Declare any non-default types here with import statements

public interface IMyAidlInterface extends android.os.IInterface
{
/** Default implementation for IMyAidlInterface. */
public static class Default implements com.wong.remoteservice.IMyAidlInterface
{
// 服务端数据

@Override public java.lang.String getString() throws android.os.RemoteException
{
return null;
}
@Override
public android.os.IBinder asBinder() {
return null;
}
}
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.wong.remoteservice.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.wong.remoteservice.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.wong.remoteservice.IMyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.wong.remoteservice.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.wong.remoteservice.IMyAidlInterface))) {
return ((com.wong.remoteservice.IMyAidlInterface)iin);
}
return new com.wong.remoteservice.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_getString:
{
data.enforceInterface(descriptor);
java.lang.String _result = this.getString();
reply.writeNoException();
reply.writeString(_result);
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements com.wong.remoteservice.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;
}
// 服务端数据

@Override public java.lang.String getString() 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_getString, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getString();
}
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static com.wong.remoteservice.IMyAidlInterface sDefaultImpl;
}
static final int TRANSACTION_getString = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
public static boolean setDefaultImpl(com.wong.remoteservice.IMyAidlInterface impl) {
if (Stub.Proxy.sDefaultImpl == null && impl != null) {
Stub.Proxy.sDefaultImpl = impl;
return true;
}
return false;
}
public static com.wong.remoteservice.IMyAidlInterface getDefaultImpl() {
return Stub.Proxy.sDefaultImpl;
}
}
// 服务端数据

public java.lang.String getString() throws android.os.RemoteException;
}

我们来仔细分析一下,这个编译后的AIDL。整体结构是这样的:

Android进程间通信之AIDL工作原理初探_AIDL


IMyAidlInterface继承了IInterface接口,IInterface接口:

Android进程间通信之AIDL工作原理初探_java_02


IBinder是用于远程对象的基础接口。轻量级远程调用机制的核心部分,为提高在进程内和跨进程调用的性能而设计。 这个接口描述了与远程对象交互使用的抽象协议,不要直接实现这个接口,而是通过继承Binder来完成。在Android中,实现远程对象(服务)的调用,就是靠Binder来实现的。

(1)Default类,提供了默认实现。

Android进程间通信之AIDL工作原理初探_java_03

(2)我们自己定义的接口getString,这个接口要在服务端实现,最终也是通过这个接口向外提供服务的。
(3)为了获得实现了getString接口的对象,我们现在要介绍最重要的Stub类:

/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.wong.remoteservice.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.wong.remoteservice.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.wong.remoteservice.IMyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.wong.remoteservice.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.wong.remoteservice.IMyAidlInterface))) {
return ((com.wong.remoteservice.IMyAidlInterface)iin);
}
return new com.wong.remoteservice.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_getString:
{
data.enforceInterface(descriptor);
java.lang.String _result = this.getString();
reply.writeNoException();
reply.writeString(_result);
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements com.wong.remoteservice.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;
}
// 服务端数据

@Override public java.lang.String getString() 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_getString, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getString();
}
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static com.wong.remoteservice.IMyAidlInterface sDefaultImpl;
}
static final int TRANSACTION_getString = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
public static boolean setDefaultImpl(com.wong.remoteservice.IMyAidlInterface impl) {
if (Stub.Proxy.sDefaultImpl == null && impl != null) {
Stub.Proxy.sDefaultImpl = impl;
return true;
}
return false;
}
public static com.wong.remoteservice.IMyAidlInterface getDefaultImpl() {
return Stub.Proxy.sDefaultImpl;
}
}

Stub的结构如下:

Android进程间通信之AIDL工作原理初探_proxy_04

  • Stub类是一个抽象类实现了IMyAidlInterface接口,但Stub并不实现getString这个方法,留给真正要对外服务的子类来实现。
  • Stub类继承了Binder,使得Stub具有访问远程对象的能力。
  • asInterface接口:
  • Android进程间通信之AIDL工作原理初探_java_05

  • 在客户端获取服务端的数据是这样获得的:
private IMyAidlInterface myBind;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBind = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {

}
};

由调用方式IMyAidlInterface.Stub.asInterface(service)可知,Stub没有被初始化,因此执行了:

return new com.wong.remoteservice.IMyAidlInterface.Stub.Proxy(obj);

返回了一个代理Proxy对象,那么我们看看定义在Stub类里的内部类Proxy:

private static class Proxy implements com.wong.remoteservice.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;
}
// 服务端数据

@Override public java.lang.String getString() 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_getString, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getString();
}
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static com.wong.remoteservice.IMyAidlInterface sDefaultImpl;
}

从这个代理可知,当我们要调用getString方法获得服务器数据时,它就会通过Binder对象的transact,向服务端请求数据。通过这种方式来完成跨进程的通信。

boolean _status = mRemote.transact(Stub.TRANSACTION_getString, _data, _reply, 0);

以上就是关于AIDL的通信原理的一部分知识。

谢谢阅读