AIDL in out inout

in out inoutThe difference between

They are both used to modify incoming parameters, with the following differences

  1. In: Variables in an object can be passed from the client to the server, and changes made by the server to the object do not affect the client.

  2. Out: The variables in the object cannot be transmitted from the client to the server. The server receives a variable with all the initial values, but the modification of the object by the server can affect the client

  3. Inout: Variables in an object can be passed to the server and changes made by the server team can also affect the client

Specific principles

An object that can be passed through Binder

  1. The Parcelable interface must be implemented. WriteToParcel (Parcel, int) has to be overwritten to indicate that the object is capable of in

  2. Optionally, you can add a readFromParcel(Parcel) method to indicate the object’s out capability. If the method is not added but is decorated with out or inout, an error is reported.

PutIPCBean (inout IPCBean IO, in IPCBean I, out IPCBean O);

The code:

IAidlInterface.Stub.ProxyClient-side proxy classes

      @Override public void putIPCBean(com.example.myapplication.bean.IPCBean inout, com.example.myapplication.bean.IPCBean in, com.example.myapplication.bean.IPCBean out) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);

          //region inout in, which writes data to a Parcel or indicates that out does not pass the object to it
          if((inout! =null)) {
            _data.writeInt(1);
            inout.writeToParcel(_data, 0);
          }
          else {
            _data.writeInt(0);
          }
          if((in! =null)) {
            _data.writeInt(1);
            in.writeToParcel(_data, 0);
          }
          else {
            _data.writeInt(0);
          }
          //endregion

          //IPC
          boolean _status = mRemote.transact(Stub.TRANSACTION_putIPCBean, _data, _reply, 0);

          _reply.readException();
          // Write the data back to the object

          //region inout, out calls the readFromParcel(Parcel) method to modify internal variables based on the value returned by the server
          // This is why classes that do not add this method will fail the out modifier if they use inout
          if ((0! =_reply.readInt())) { inout.readFromParcel(_reply); }if ((0! =_reply.readInt())) { out.readFromParcel(_reply); }//endregion
        }
        finally{ _reply.recycle(); _data.recycle(); }}Copy the code

Long for the total

From the client side:

  1. An object decorated out will not call writeToParcel(Parcel, int), that is, will not be written to a Parcel, so the server will not receive it.

  2. Objects decorated with inout, out call readFromParcel(Parcel), which modifies its own internal variables according to changes on the server side. This is why classes that do not add this method will report an error if they use the inout, out modifier.

IAidlInterface.StubThe implementation of the server side

    // The variable name has been changed to the direction of the corresponding data
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    {
      / /... Omit other irrelevant
      switch (code)
      {
        case TRANSACTION_putIPCBean:
        {
          data.enforceInterface(descriptor);

          //region inout, in, see that the objects are generated from the Parcel passed from the client,
          // That is, the variable of the object in the client can be passed to the server
          com.example.myapplication.bean.IPCBean inout;
          if ((0! =data.readInt())) { inout = com.example.myapplication.bean.IPCBean.CREATOR.createFromParcel(data); }else {
            inout = null;
          }
          com.example.myapplication.bean.IPCBean in;
          if ((0! =data.readInt())) { in = com.example.myapplication.bean.IPCBean.CREATOR.createFromParcel(data); }else {
            in = null;
          }
          //endregion

          //region out, constructs the object directly, so the internal variables are all initial values
          com.example.myapplication.bean.IPCBean out;
          out = new com.example.myapplication.bean.IPCBean();
          //endregion

          this.putIPCBean(inout, in, out);

          // Write the data back to the client
          reply.writeNoException();

          //region inout, out Changes to the incoming object on the server are written back to the Parcel and can be passed back to the client
          if((inout! =null)) {
            reply.writeInt(1);
            inout.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
          }
          else {
            reply.writeInt(0);
          }
          if((out! =null)) {
            reply.writeInt(1);
            out.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
          }
          else {
            reply.writeInt(0);
          }
          //endregion

          return true; }}default:
        {
          return super.onTransact(code, data, reply, flags); }}}Copy the code

Long for the total

From the server side:

  1. When constructing objects, only objects decorated in inout are built (because out objects don’t write parcels, as mentioned above).

  2. When reply data is written, only the writeToParcel(Parcel, int) method of the object decorated by inOut is called.