Android AIDL 理解及開發要點

1). development/samples/ApiDemos/src/com/example/android/apis/app/
*.aidl, Localservice**.java RemoteService*.java, ServiceStartArguments*.java

2). 深入解析Android 的AIDL Interface (高煥堂)
http://wenku.baidu.com/view/920f92ea998fcc22bcd10d28.html

3). http://wzw19191.blog.163.com/blog/static/131135470201051675520369/

在android中,進程通訊是通過aidl機制來完成的。aidl模型如下:

|<--------------------aidl---------------------->|
client端 -->proxy ----------parcel數據包-------- stub<---server端
也就是說:proxy+parcel+stub構成了aidl.只不過,proxy運行在客戶進程,而 stub運行在服務端進程。當你通過aidl去訪問服務端時,客戶端會阻塞在proxy,服務端處理完後,通知proxy返回。

補充1:
應用程序獲取相關服務的代碼:
private AlarmManager getAlarmManager() {
synchronized (sSync) {
if (sAlarmManager == null) {
IBinder b = ServiceManager.getService(ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
sAlarmManager = new AlarmManager(service);
}
}
return sAlarmManager;
}


補充2:
AIDL文件生成的java文件中的Stub 類。
public static abstract class Stub extends android.os.Binder implements
android.net.softap.ISoftApManager {
private static final java.lang.String DESCRIPTOR = "android.net.softap.ISoftApManager";

/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}

/**
* Cast an IBinder object into an ISoftApManager interface, generating a
* proxy if needed.
*/
public static android.net.softap.ISoftApManager asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface) obj
.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof android.net.softap.ISoftApManager))) {
return ((android.net.softap.ISoftApManager) iin);
}
return new android.net.softap.ISoftApManager.Stub.Proxy(obj);
}

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 {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getApEnabledState: {
data.enforceInterface(DESCRIPTOR);
int _result = this.getApEnabledState();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_setApEnabled: {
data.enforceInterface(DESCRIPTOR);
boolean _arg0;
_arg0 = (0 != data.readInt());
boolean _result = this.setApEnabled(_arg0);
reply.writeNoException();
reply.writeInt(((_result) ? (1) : (0)));
return true;
}
case TRANSACTION_setApSettings: {
data.enforceInterface(DESCRIPTOR);
android.net.softap.SoftApConfigure _arg0;
if ((0 != data.readInt())) {
_arg0 = android.net.softap.SoftApConfigure.CREATOR
.createFromParcel(data);
} else {
_arg0 = null;
}
boolean _result = this.setApSettings(_arg0);
reply.writeNoException();
reply.writeInt(((_result) ? (1) : (0)));
return true;
}
case TRANSACTION_getApSettings: {
data.enforceInterface(DESCRIPTOR);
android.net.softap.SoftApConfigure _result = this
.getApSettings();
reply.writeNoException();
if ((_result != null)) {
reply.writeInt(1);
_result
.writeToParcel(
reply,
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
reply.writeInt(0);
}
return true;
}
}
return super.onTransact(code, data, reply, flags);
}

private static class Proxy implements android.net.softap.ISoftApManager {
private android.os.IBinder mRemote;

Proxy(android.os.IBinder remote) {
mRemote = remote;
}

public android.os.IBinder asBinder() {
return mRemote;
}

public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}

public int getApEnabledState() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getApEnabledState, _data,
_reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

public boolean setApEnabled(boolean enable)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(((enable) ? (1) : (0)));
mRemote.transact(Stub.TRANSACTION_setApEnabled, _data,
_reply, 0);
_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

public boolean setApSettings(
android.net.softap.SoftApConfigure datas)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((datas != null)) {
_data.writeInt(1);
datas.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_setApSettings, _data,
_reply, 0);
_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

public android.net.softap.SoftApConfigure getApSettings()
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
android.net.softap.SoftApConfigure _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getApSettings, _data,
_reply, 0);
_reply.readException();
if ((0 != _reply.readInt())) {
_result = android.net.softap.SoftApConfigure.CREATOR
.createFromParcel(_reply);
} else {
_result = null;
}
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}

static final int TRANSACTION_getApEnabledState = (IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_setApEnabled = (IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_setApSettings = (IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_getApSettings = (IBinder.FIRST_CALL_TRANSACTION + 3);
}

補充3:
通常服務程序該Stub類,也即間接繼承了 android.os.Binder,進而可以作爲 SystemManager.addService 等的參數而使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章