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();


.