【并发编程】AIDL关键字

时间:2024-04-02 20:34:42
oneway
Oneway interfaces
In early betas, the Android IPC was strictly synchronous. This means that service invocations had to wait for the return value of the remote method to arrive back to the caller. This is generally an advantage because the caller can be sure that the called service received the invocation by the time the remote method returns. In some cases, however, this causes the caller to wait unnecessarily. If synchronicity is not required and the method has no return value, oneway AIDL interfaces may be used.
Oneway methods are specified by addind the oneway keyword to the AIDL interface definition.
package com.elfylin;
oneway interface IMyServiceOneway {
String getValue();
}
    package com.elfylin;
public interface IMyServiceOneway extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.elfylin.IMyServiceOneway
{
private static final java.lang.String DESCRIPTOR = "com.elfylin.IMyServiceOneway";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.elfylin.IMyServiceOneway interface,
* generating a proxy if needed.
*/
public static com.elfylin.IMyServiceOneway 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 com.elfylin.IMyServiceOneway))) {
return ((com.elfylin.IMyServiceOneway)iin);
}
return new com.elfylin.IMyServiceOneway.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_getValue:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _result = this.getValue();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.elfylin.IMyServiceOneway
{
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 java.lang.String getValue() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getValue, _data, null, android.os.IBinder.FLAG_ONEWAY);
}
finally {
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_getValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.lang.String getValue() throws android.os.RemoteException;
}

in、out与inout

    First, for all non-primitive parameters, you need to specify one of three directional types: in, out, or inout.
The in type indicates that they are used only for input and that your client won’t see any changes that the
Service does to this object. The out type indicates that the input object contains no relevant data but will
be populated with data by the Service that’s relevant in the response from the method. The inout type
is a combination of both types. It’s very important to use only the type that’s needed because there’s a cost
associated with each type.
    Another thing to remember is that for all custom classes used in communication, you need to create an AIDL file
that declares your class as a Parcelable.

在使用aidl传输数据时,对于非基本数据类型,也不是String和CharSequence类型的(即Parcelable类型),需要有方向指示,包括in、out和inout。

下表为in和out在远程传输中的作用。

  Stub.ontransact() Proxy.callback(Data data)
in 

接收远程传输的数据(Data) 输入本地数据(Data)
中间过程 本地调用(修改Data) 远程调用(给远程传输Data)
out
将经过本地调用修改过后的Data,返回给远端

获取远程调用之后,传输过来的远端数据(Data)

a、server in client in
03-07 14:23:13.250: I/System.out(16307): client in: ZLData [data=Client]
03-07 14:23:13.250: I/System.out(16579): Server in: ZLData [data=Client]
03-07 14:23:13.250: I/System.out(16579): Server out:ZLData [data=server]
03-07 14:23:13.250: I/System.out(16307): client out: ZLData [data=Client] b、server in client out
03-07 14:22:00.980: I/System.out(16009): client in: ZLData [data=Client]
03-07 14:22:00.980: I/System.out(16050): Server in: null
03-07 14:22:00.980: I/System.out(16050): Server out:ZLData [data=server]
03-07 14:22:00.980: I/System.out(16009): client out: ZLData [data=Client] c、server out client in
03-07 14:22:37.170: I/System.out(16307): client in: ZLData [data=Client]
03-07 14:22:37.170: I/System.out(16421): Server in: ZLData [data=]
03-07 14:22:37.170: I/System.out(16421): Server out:ZLData [data=server]
03-07 14:22:37.170: I/System.out(16307): client out: ZLData [data=Client] d、server out client out
03-07 14:21:15.640: I/System.out(8592): client in: ZLData [data=Client]
03-07 14:21:15.640: I/System.out(15762): Server in: ZLData [data=]
03-07 14:21:15.640: I/System.out(15762): Server out:ZLData [data=server]
03-07 14:21:15.640: I/System.out(8592): client out: ZLData [data=server]

总结

  • 如果client不需要传输数据给server,client只需要处理经过server处理过后的数据,那么client和server都为out。
  • 如果client只需要传输数据给server,而不需要处理返回的数据,那么client和server都为in。
  • 如果client需要传输数据给server,而且需要处理返回的数据,则client和server都为inout。

in,out会影响进程间传输的数据完整性。具体详细可查看配置不同的in、out 的情况下,aidl生成对应的java文件中Stub.ontransact() 和Proxy.yourMethod();