我們新建了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。整體結構是這樣的:
IMyAidlInterface繼承了IInterface接口,IInterface接口:
IBinder是用於遠程對象的基礎接口。輕量級遠程調用機制的核心部分,爲提高在進程內和跨進程調用的性能而設計。 這個接口描述了與遠程對象交互使用的抽象協議,不要直接實現這個接口,而是通過繼承Binder來完成。在Android中,實現遠程對象(服務)的調用,就是靠Binder來實現的。
(1)Default類,提供了默認實現。
(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的結構如下:
- Stub類是一個抽象類實現了IMyAidlInterface接口,但Stub並不實現getString這個方法,留給真正要對外服務的子類來實現。
- Stub類繼承了Binder,使得Stub具有訪問遠程對象的能力。
- asInterface接口:
在客戶端獲取服務端的數據是這樣獲得的:
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的通信原理的一部分知識。
謝謝閱讀