AIDL 关键字 in out inout oneway 解析

2024-05-08  本文已影响0人  竖起大拇指

1.关键字的作用

in out inout 是 aidl中的 directional tag,表示了在跨进程通信中数据的流向:

2.关键字解析

 
import android.os.Parcel;
import android.os.Parcelable;
 
public class Book implements Parcelable{
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getPrice() {
        return price;
    }
 
    public void setPrice(int price) {
        this.price = price;
    }
 
    private String name;
    private int price;
    public Book(){}
 
    public Book(Parcel in) {
        name = in.readString();
        price = in.readInt();
    }
 
    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }
 
        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };
 
    @Override
    public int describeContents() {
        return 0;
    }
 
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(price);
    }
 
    /**
     * 参数是一个Parcel,用它来存储与传输数据
     * @param dest
     */
    public void readFromParcel(Parcel dest) {
        //注意,此处的读值顺序应当是和writeToParcel()方法中一致的
        name = dest.readString();
        price = dest.readInt();
    }
 
    //方便打印数据
    @Override
    public String toString() {
        return "name : " + name + " , price : " + price;
    }
}

Book.aidl 内容如下:

package com.yuandaima;
 
parcelable Book;

IHelloService.aidl

package com.yuandaima;
 
import com.yuandaima.Book;
 
interface IHelloService
{
 int sayhelloin(in Book book);
 int sayhelloout(out Book book);
 int sayhelloinout(inout Book book);
 oneway void sayhellooneway(in Book book);
}

我们来看下内部的 Proxy 类的实现:

    private static class Proxy implements com.yuandaima.IHelloService
    {
      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;
      }
 
      //in 表示数据从客户端传递给服务端
      @Override public int sayhelloin(com.yuandaima.Book book) 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);
          if ((book!=null)) {
            _data.writeInt(1);
            book.writeToParcel(_data, 0); //数据写入 Parcel 对象
          }
          else {
            _data.writeInt(0);
          }
          boolean _status = mRemote.transact(Stub.TRANSACTION_sayhelloin, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().sayhelloin(book);
          }
          _reply.readException();
          _result = _reply.readInt();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
 
      //out 表示数据从服务端回传给客户端
      @Override public int sayhelloout(com.yuandaima.Book book) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        int _result;
 
        //发送前不会向 Parcel 写入数据
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          boolean _status = mRemote.transact(Stub.TRANSACTION_sayhelloout, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().sayhelloout(book);
          }
          _reply.readException();
          _result = _reply.readInt();
          if ((0!=_reply.readInt())) {
            book.readFromParcel(_reply); //从返回数据中读出 book
          }
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
 
      // inout 表示数据从客户端传递给服务端,同时服务端也会传回客户端
      @Override public int sayhelloinout(com.yuandaima.Book book) 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);
          if ((book!=null)) {
            _data.writeInt(1);
            book.writeToParcel(_data, 0); // 数据写入 Parcel 对象
          }
          else {
            _data.writeInt(0);
          }
          boolean _status = mRemote.transact(Stub.TRANSACTION_sayhelloinout, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().sayhelloinout(book);
          }
          _reply.readException();
          _result = _reply.readInt();
          if ((0!=_reply.readInt())) {
            book.readFromParcel(_reply);   //从返回数据中读出 book
          }
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      @Override public void sayhellooneway(com.yuandaima.Book book) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          if ((book!=null)) {
            _data.writeInt(1);
            book.writeToParcel(_data, 0);
          }
          else {
            _data.writeInt(0);
          }
          //发送数据时,最后一个参数是 FLAG_ONEWAY,表示调用是异步的
          boolean _status = mRemote.transact(Stub.TRANSACTION_sayhellooneway, _data, null, android.os.IBinder.FLAG_ONEWAY);
          if (!_status && getDefaultImpl() != null) {
            getDefaultImpl().sayhellooneway(book);
            return;
          }
        }
        finally {
          _data.recycle();
        }
      }
      public static com.yuandaima.IHelloService sDefaultImpl;
    }

接着我们在看先服务端 onTransact 中是如何处理数据的:

    @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_sayhelloin:
        {
          data.enforceInterface(descriptor);
          com.yuandaima.Book _arg0;
          if ((0!=data.readInt())) {
            //从 Parcel 中读出数据
            _arg0 = com.yuandaima.Book.CREATOR.createFromParcel(data);
          }
          else {
            _arg0 = null;
          }
          int _result = this.sayhelloin(_arg0);
          reply.writeNoException();
          reply.writeInt(_result);
          return true;
        }
        case TRANSACTION_sayhelloout:
        {
          data.enforceInterface(descriptor);
          com.yuandaima.Book _arg0;
          _arg0 = new com.yuandaima.Book();
          int _result = this.sayhelloout(_arg0);
          reply.writeNoException();
          reply.writeInt(_result);
          if ((_arg0!=null)) {
            reply.writeInt(1);
            // 将数据写入需要返回的 Parcel 对象中
            _arg0.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
          }
          else {
            reply.writeInt(0);
          }
          return true;
        }
        case TRANSACTION_sayhelloinout:
        {
          data.enforceInterface(descriptor);
          com.yuandaima.Book _arg0;
          if ((0!=data.readInt())) {
            //读取数据
            _arg0 = com.yuandaima.Book.CREATOR.createFromParcel(data);
          }
          else {
            _arg0 = null;
          }
          int _result = this.sayhelloinout(_arg0);
          reply.writeNoException();
          reply.writeInt(_result);
          if ((_arg0!=null)) {
            reply.writeInt(1);
            //写入数据
            _arg0.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
          }
          else {
            reply.writeInt(0);
          }
          return true;
        }
        case TRANSACTION_sayhellooneway:
        {
          data.enforceInterface(descriptor);
          com.yuandaima.Book _arg0;
          if ((0!=data.readInt())) {
            _arg0 = com.yuandaima.Book.CREATOR.createFromParcel(data);
          }
          else {
            _arg0 = null;
          }
          this.sayhellooneway(_arg0);
          return true;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
    }

从源码我们可以看出,in out 的实现是通过是否从 Parcel 对象中读写数据实现的。oneway 是通过将 transact 方法最后一个参数设置为 FLAG_ONEWAY 实现的。

上一篇 下一篇

猜你喜欢

热点阅读