Android Binder系列之AIDL分析(3)

前言

上一篇文章讲了AIDL的使用,我们知道AIDL是方便我们使用Binder的插件,那么AIDL到底做了哪些事情呢?不知道你有没有看过Activity的启动流程,最终会跨进程调用ActivityManageService,但是他并没有使用AIDL呀,他是怎么使用Binder的呢?看完这篇文章你就知道了。

由于跨进程并不能直接传递对象,所以除了一些基本类型之外要传递的对象都需要先进行序列化操作,java中的序列化方式有两种:Serializable和Parcelable,Parcelable的性能更好所以是安卓推荐的方式。

代码结构分析

还记得上一篇文章写好AIDL后会clean一下项目吗,这一步操作是为了生成一个文件IMyAidlInterface.java,这个接口就是Binder通信的真正执行者,看一下这个接口的结构:
在这里插入图片描述
这个接口中有三个方法:basicTypes、getPeople、addPeople。
都是我们在IMyAidlInterface.aidl中定义的通信方法,接口中有两个内部类:Default和Stub,Default我们不用管,Stub这个名字熟悉吗?这不就是我们在Service中定义和返回的binder吗:

    private IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
            Log.e(TAG, "basicTypes: anInt=" + anInt + " aLong=" + aLong + " aBoolean=" + aBoolean +
                    " aFloat=" + aFloat + " aDouble=" + aDouble + " aString=" + aString);
        }

        @Override
        public People getPeople() throws RemoteException {
            return people;
        }

        @Override
        public void addPeople(People people) throws RemoteException {
            Log.e(TAG, "addPeople: " + people.toString());
        }
    };

原来这个类是从这里来的,另外Stub中还有一个内部类Proxy,这个类就这么多东西,我们看一下他全部的代码:

public interface IMyAidlInterface extends android.os.IInterface
{
  /** Default implementation for IMyAidlInterface. */
  public static class Default implements com.czy.server.IMyAidlInterface
  {
    /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
    @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
    {
    }
    @Override public com.czy.server.People getPeople() throws android.os.RemoteException
    {
      return null;
    }
    @Override public void addPeople(com.czy.server.People people) throws android.os.RemoteException
    {
    }
    @Override
    public android.os.IBinder asBinder() {
      return null;
    }
  }
  /** Local-side IPC implementation stub class. */
  public static abstract class Stub extends android.os.Binder implements com.czy.server.IMyAidlInterface
  {
    private static final java.lang.String DESCRIPTOR = "com.czy.server.IMyAidlInterface";
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
      this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an com.czy.server.IMyAidlInterface interface,
     * generating a proxy if needed.
     */
    public static com.czy.server.IMyAidlInterface asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof com.czy.server.IMyAidlInterface))) {
        return ((com.czy.server.IMyAidlInterface)iin);
      }
      return new com.czy.server.IMyAidlInterface.Stub.Proxy(obj);
    }
    @Override 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
    {
      java.lang.String descriptor = DESCRIPTOR;
      switch (code)
      {
        case INTERFACE_TRANSACTION:
        {
          reply.writeString(descriptor);
          return true;
        }
        case TRANSACTION_basicTypes:
        {
          data.enforceInterface(descriptor);
          int _arg0;
          _arg0 = data.readInt();
          long _arg1;
          _arg1 = data.readLong();
          boolean _arg2;
          _arg2 = (0!=data.readInt());
          float _arg3;
          _arg3 = data.readFloat();
          double _arg4;
          _arg4 = data.readDouble();
          java.lang.String _arg5;
          _arg5 = data.readString();
          this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
          reply.writeNoException();
          return true;
        }
        case TRANSACTION_getPeople:
        {
          data.enforceInterface(descriptor);
          com.czy.server.People _result = this.getPeople();
          reply.writeNoException();
          if ((_result!=null)) {
            reply.writeInt(1);
            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
          }
          else {
            reply.writeInt(0);
          }
          return true;
        }
        case TRANSACTION_addPeople:
        {
          data.enforceInterface(descriptor);
          com.czy.server.People _arg0;
          if ((0!=data.readInt())) {
            _arg0 = com.czy.server.People.CREATOR.createFromParcel(data);
          }
          else {
            _arg0 = null;
          }
          this.addPeople(_arg0);
          reply.writeNoException();
          return true;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
    }
    private static class Proxy implements com.czy.server.IMyAidlInterface
    {
      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;
      }
      /**
           * Demonstrates some basic types that you can use as parameters
           * and return values in AIDL.
           */
      @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeInt(anInt);
          _data.writeLong(aLong);
          _data.writeInt(((aBoolean)?(1):(0)));
          _data.writeFloat(aFloat);
          _data.writeDouble(aDouble);
          _data.writeString(aString);
          boolean _status = mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            getDefaultImpl().basicTypes(anInt, aLong, aBoolean, aFloat, aDouble, aString);
            return;
          }
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
      @Override public com.czy.server.People getPeople() throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        com.czy.server.People _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          boolean _status = mRemote.transact(Stub.TRANSACTION_getPeople, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().getPeople();
          }
          _reply.readException();
          if ((0!=_reply.readInt())) {
            _result = com.czy.server.People.CREATOR.createFromParcel(_reply);
          }
          else {
            _result = null;
          }
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      @Override public void addPeople(com.czy.server.People people) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          if ((people!=null)) {
            _data.writeInt(1);
            people.writeToParcel(_data, 0);
          }
          else {
            _data.writeInt(0);
          }
          boolean _status = mRemote.transact(Stub.TRANSACTION_addPeople, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            getDefaultImpl().addPeople(people);
            return;
          }
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
      public static com.czy.server.IMyAidlInterface sDefaultImpl;
    }
    static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_getPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    static final int TRANSACTION_addPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
    public static boolean setDefaultImpl(com.czy.server.IMyAidlInterface impl) {
      if (Stub.Proxy.sDefaultImpl == null && impl != null) {
        Stub.Proxy.sDefaultImpl = impl;
        return true;
      }
      return false;
    }
    public static com.czy.server.IMyAidlInterface getDefaultImpl() {
      return Stub.Proxy.sDefaultImpl;
    }
  }
  /**
       * Demonstrates some basic types that you can use as parameters
       * and return values in AIDL.
       */
  public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
  public com.czy.server.People getPeople() throws android.os.RemoteException;
  public void addPeople(com.czy.server.People people) throws android.os.RemoteException;
}

代码分析

1.IMyAidlInterface

删除其中的内部类单纯看这个接口比较简单:

    public interface IMyAidlInterface extends android.os.IInterface {
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
        public com.czy.server.People getPeople() throws android.os.RemoteException;
        public void addPeople(com.czy.server.People people) throws android.os.RemoteException;
    }

这是一个继承了IInterface的接口,里面定义了进行通信的三个方法,这个接口没有什么实际的意义,主要是Stub和Proxy都实现它。

2.IMyAidlInterface.Stub

同样删除他的内部类Proxy来看他的代码:

public static abstract class Stub extends android.os.Binder implements com.czy.server.IMyAidlInterface {
        private static final java.lang.String DESCRIPTOR = "com.czy.server.IMyAidlInterface";

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

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

        @Override
        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 {
            java.lang.String descriptor = DESCRIPTOR;
            switch (code) {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(descriptor);
                    return true;
                }
                case TRANSACTION_basicTypes: {
                    data.enforceInterface(descriptor);
                    int _arg0;
                    _arg0 = data.readInt();
                    long _arg1;
                    _arg1 = data.readLong();
                    boolean _arg2;
                    _arg2 = (0 != data.readInt());
                    float _arg3;
                    _arg3 = data.readFloat();
                    double _arg4;
                    _arg4 = data.readDouble();
                    java.lang.String _arg5;
                    _arg5 = data.readString();
                    this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_getPeople: {
                    data.enforceInterface(descriptor);
                    com.czy.server.People _result = this.getPeople();
                    reply.writeNoException();
                    if ((_result != null)) {
                        reply.writeInt(1);
                        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    } else {
                        reply.writeInt(0);
                    }
                    return true;
                }
                case TRANSACTION_addPeople: {
                    data.enforceInterface(descriptor);
                    com.czy.server.People _arg0;
                    if ((0 != data.readInt())) {
                        _arg0 = com.czy.server.People.CREATOR.createFromParcel(data);
                    } else {
                        _arg0 = null;
                    }
                    this.addPeople(_arg0);
                    reply.writeNoException();
                    return true;
                }
                default: {
                    return super.onTransact(code, data, reply, flags);
                }
            }
        }

        static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_getPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
        static final int TRANSACTION_addPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);

        public static boolean setDefaultImpl(com.czy.server.IMyAidlInterface impl) {
            if (Stub.Proxy.sDefaultImpl == null && impl != null) {
                Stub.Proxy.sDefaultImpl = impl;
                return true;
            }
            return false;
        }

        public static com.czy.server.IMyAidlInterface getDefaultImpl() {
            return Stub.Proxy.sDefaultImpl;
        }
    }

Stub继承了Binder并实现了IMyAidlInterface,我们来一个个分析他的方法:
Stub()
首先他的构造函数调用了父类的attachInterface方法,并将本身和Stub的唯一标识DESCRIPTOR传递过,看一下这个方法:

    public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
        mOwner = owner;
        mDescriptor = descriptor;
    }

只是将传递的参数保存起来,两个参数后面会用到。

asInterface
不知道大家还记不记得这是在连接远程服务之后将Binder对象转化为IMyAidlInterface接口类型的方法:

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

看一下这个方法的具体内容:

    public static com.czy.server.IMyAidlInterface asInterface(android.os.IBinder obj) {
        if ((obj == null)) {
            return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin != null) && (iin instanceof com.czy.server.IMyAidlInterface))) {
            return ((com.czy.server.IMyAidlInterface) iin);
        }
        return new com.czy.server.IMyAidlInterface.Stub.Proxy(obj);
    }

这里根据参数不同会有两种情况,如果服务端和客户端在同一个进程就会返回iin,如果在不同进程就会new一个Proxy返回。
那么怎么判断在不在一个进程呢,这就看queryLocalInterface方法了:

    public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
        if (mDescriptor != null && mDescriptor.equals(descriptor)) {
            return mOwner;
        }
        return null;
    }

这里用到了mDescriptor,还记得Stub的构造函数吗,这是DESCRIPTOR的值,这里就是判断是不是同一个Stub,是就返回自己。
通过这个判断我们可以知道IMyAidlInterface.Stub.asInterface(service)中的service和IMyAidlInterface.Stub是不是一个类,这只是一个类型判断,但是这也不能区分在不在一个进程呀,后面还有一个判断

(iin instanceof com.czy.server.IMyAidlInterface)

这还是类型判断,确保转换的对象是正确的,看来一开始的思路错了,不卖关子了,其实同一个进程和不同进程传递中asInterface(android.os.IBinder obj)传递的参数是不一样的,同一个进程是服务端返回的binder(IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub()),而不同进程是BinderProxy,这是为什么暂时不说,BinderProxy和Binder一样实现了IBinder接口,看一下他的queryLocalInterface方法

public IInterface queryLocalInterface(String descriptor) {
        return null;
    }

这里是百分百返回null,所以asInterface最后也就返回了Proxy。

asBinder

    @Override
    public android.os.IBinder asBinder() {
        return this;
    }

返回自己没什么说的。

TRANSACTION
Stub定义了很多TRANSACTION开头的常量:

    static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_getPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    static final int TRANSACTION_addPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);

这个是用来在不同进程间标识一个方法的方式,跨进程的方法并不能直接调用,所以服务端收到消息后知道你调用那个方法,就是通过这个来标识的。

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_basicTypes: {
                data.enforceInterface(descriptor);
                int _arg0;
                _arg0 = data.readInt();
                long _arg1;
                _arg1 = data.readLong();
                boolean _arg2;
                _arg2 = (0 != data.readInt());
                float _arg3;
                _arg3 = data.readFloat();
                double _arg4;
                _arg4 = data.readDouble();
                java.lang.String _arg5;
                _arg5 = data.readString();
                this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
                reply.writeNoException();
                return true;
            }
            case TRANSACTION_getPeople: {
                data.enforceInterface(descriptor);
                //调用自己的getPeople方法
                com.czy.server.People _result = this.getPeople();
                reply.writeNoException();
                if ((_result != null)) {
                    reply.writeInt(1);
                    //将返回值写入reply中
                    _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                } else {
                    reply.writeInt(0);
                }
                return true;
            }
            case TRANSACTION_addPeople: {
                data.enforceInterface(descriptor);
                com.czy.server.People _arg0;
                if ((0 != data.readInt())) {
                    //取出data中的参数
                    _arg0 = com.czy.server.People.CREATOR.createFromParcel(data);
                } else {
                    _arg0 = null;
                }
                //调用自己的addPeople方法
                this.addPeople(_arg0);
                reply.writeNoException();
                return true;
            }
            default: {
                return super.onTransact(code, data, reply, flags);
            }
        }
    }

首先通过code也就是TRANSACTION判断调用的那一个方法,比如TRANSACTION_getPeople,先是调用了自己的getPeople方法,也就是MyService中的getPeople方法,然后向reply中写入返回值。
如果是有参数的方法,比如TRANSACTION_addPeople,会从data中取出参数,然后调用自己的addPeople方法并把参数传入。
不知道你注意到了没有,上面的取出参数和写入返回值就是对象的序列化和反序列化。

3.IMyAidlInterface.Stub.Proxy

在不同的进程中asInterface会返回Proxy,那么Proxy到底做了什么呢?

 private static class Proxy implements com.czy.server.IMyAidlInterface {
        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;
        }

        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                _data.writeInt(anInt);
                _data.writeLong(aLong);
                _data.writeInt(((aBoolean) ? (1) : (0)));
                _data.writeFloat(aFloat);
                _data.writeDouble(aDouble);
                _data.writeString(aString);
                boolean _status = mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
                if (!_status && getDefaultImpl() != null) {
                    getDefaultImpl().basicTypes(anInt, aLong, aBoolean, aFloat, aDouble, aString);
                    return;
                }
                _reply.readException();
            } finally {
                _reply.recycle();
                _data.recycle();
            }
        }

        @Override
        public com.czy.server.People getPeople() throws android.os.RemoteException {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            com.czy.server.People _result;
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                boolean _status = mRemote.transact(Stub.TRANSACTION_getPeople, _data, _reply, 0);
                if (!_status && getDefaultImpl() != null) {
                    return getDefaultImpl().getPeople();
                }
                _reply.readException();
                if ((0 != _reply.readInt())) {
                    _result = com.czy.server.People.CREATOR.createFromParcel(_reply);
                } else {
                    _result = null;
                }
            } finally {
                _reply.recycle();
                _data.recycle();
            }
            return _result;
        }

        @Override
        public void addPeople(com.czy.server.People people) throws android.os.RemoteException {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                if ((people != null)) {
                    _data.writeInt(1);
                    people.writeToParcel(_data, 0);
                } else {
                    _data.writeInt(0);
                }
                boolean _status = mRemote.transact(Stub.TRANSACTION_addPeople, _data, _reply, 0);
                if (!_status && getDefaultImpl() != null) {
                    getDefaultImpl().addPeople(people);
                    return;
                }
                _reply.readException();
            } finally {
                _reply.recycle();
                _data.recycle();
            }
        }

        public static com.czy.server.IMyAidlInterface sDefaultImpl;
    }

Proxy也实现了IMyAidlInterface ,既然asInterface返回的是Proxy,那么调用的getPeople和addPeople就是这里面的方法了。
实际上Proxy里也就只有这些方法。

getPeople

  @Override
    public com.czy.server.People getPeople() throws android.os.RemoteException {
        //初始化参数Parcel 
        android.os.Parcel _data = android.os.Parcel.obtain();
        //初始化返回值Parcel 
        android.os.Parcel _reply = android.os.Parcel.obtain();
        com.czy.server.People _result;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            //远程调用方法
            boolean _status = mRemote.transact(Stub.TRANSACTION_getPeople, _data, _reply, 0);
            if (!_status && getDefaultImpl() != null) {
                return getDefaultImpl().getPeople();
            }
            _reply.readException();
            if ((0 != _reply.readInt())) {
                //获取返回值对象
                _result = com.czy.server.People.CREATOR.createFromParcel(_reply);
            } else {
                _result = null;
            }
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return _result;
    }

首先初始化了参数和返回值Parcel,由于没有参数所以_data中并没有值,然后就去调用transact方法远程调用getPeople,调用完成之后将_reply中的返回值反序列化,最后将反序列化后的返回值返回给调用方。

addPeople
和getPeople类似,只是没有返回值就不看了。

到这里整个IMyAidlInterface.java就讲完了,Binder的应用层也就讲完了,在往下就要牵扯到framework层了,基本上理解上面讲的那么多就够日常使用了。为了验证你已经理解了我们还要做一件事情,就是把IMyAidlInterface.java这个文件拆分(其实上面分析的时候我已经把他拆开了),我们看到ActivityManageService并没有Stub、Proxy这些就是因为他没有放到一起,而且Stub、Proxy这些名字也是可以随意改的,我就不把过程写出来了,直接把已经分离的代码贴出来。

代码分离

在这里插入图片描述

1.IMyAidlInterface

public interface IMyAidlInterface extends android.os.IInterface {
    static final java.lang.String DESCRIPTOR = "com.czy.server.IMyAidlInterface";

    static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_getPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    static final int TRANSACTION_addPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);

    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;

    public com.czy.server.People getPeople() throws android.os.RemoteException;

    public void addPeople(com.czy.server.People people) throws android.os.RemoteException;
}

2.IMyAidlInterfaceStubImpl

public abstract class IMyAidlInterfaceStubImpl extends android.os.Binder implements com.czy.server.IMyAidlInterface {

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

    /**
     * Cast an IBinder object into an com.czy.server.IMyAidlInterface interface,
     * generating a proxy if needed.
     */
    public static com.czy.server.IMyAidlInterface asInterface(android.os.IBinder obj) {
        if ((obj == null)) {
            return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin != null) && (iin instanceof com.czy.server.IMyAidlInterface))) {
            return ((com.czy.server.IMyAidlInterface) iin);
        }
        return new IMyAidlInterfaceProxyImpl(obj);
    }

    @Override
    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 {
        java.lang.String descriptor = DESCRIPTOR;
        switch (code) {
            case INTERFACE_TRANSACTION: {
                reply.writeString(descriptor);
                return true;
            }
            case TRANSACTION_basicTypes: {
                data.enforceInterface(descriptor);
                int _arg0;
                _arg0 = data.readInt();
                long _arg1;
                _arg1 = data.readLong();
                boolean _arg2;
                _arg2 = (0 != data.readInt());
                float _arg3;
                _arg3 = data.readFloat();
                double _arg4;
                _arg4 = data.readDouble();
                java.lang.String _arg5;
                _arg5 = data.readString();
                this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
                reply.writeNoException();
                return true;
            }
            case TRANSACTION_getPeople: {
                data.enforceInterface(descriptor);
                com.czy.server.People _result = this.getPeople();
                reply.writeNoException();
                if ((_result != null)) {
                    reply.writeInt(1);
                    _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                } else {
                    reply.writeInt(0);
                }
                return true;
            }
            case TRANSACTION_addPeople: {
                data.enforceInterface(descriptor);
                com.czy.server.People _arg0;
                if ((0 != data.readInt())) {
                    _arg0 = com.czy.server.People.CREATOR.createFromParcel(data);
                } else {
                    _arg0 = null;
                }
                this.addPeople(_arg0);
                reply.writeNoException();
                return true;
            }
            default: {
                return super.onTransact(code, data, reply, flags);
            }
        }
    }

    public static boolean setDefaultImpl(com.czy.server.IMyAidlInterface impl) {
        if (IMyAidlInterfaceProxyImpl.sDefaultImpl == null && impl != null) {
            IMyAidlInterfaceProxyImpl.sDefaultImpl = impl;
            return true;
        }
        return false;
    }

    public static com.czy.server.IMyAidlInterface getDefaultImpl() {
        return IMyAidlInterfaceProxyImpl.sDefaultImpl;
    }
}

3.IMyAidlInterfaceProxyImpl

public class IMyAidlInterfaceProxyImpl implements com.czy.server.IMyAidlInterface {
    private android.os.IBinder mRemote;

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

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

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

    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    @Override
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeInt(anInt);
            _data.writeLong(aLong);
            _data.writeInt(((aBoolean) ? (1) : (0)));
            _data.writeFloat(aFloat);
            _data.writeDouble(aDouble);
            _data.writeString(aString);
            boolean _status = mRemote.transact(TRANSACTION_basicTypes, _data, _reply, 0);
            if (!_status && IMyAidlInterfaceStubImpl.getDefaultImpl() != null) {
                IMyAidlInterfaceStubImpl.getDefaultImpl().basicTypes(anInt, aLong, aBoolean, aFloat, aDouble, aString);
                return;
            }
            _reply.readException();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
    }

    @Override
    public com.czy.server.People getPeople() throws android.os.RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        com.czy.server.People _result;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            boolean _status = mRemote.transact(TRANSACTION_getPeople, _data, _reply, 0);
            if (!_status && IMyAidlInterfaceStubImpl.getDefaultImpl() != null) {
                return IMyAidlInterfaceStubImpl.getDefaultImpl().getPeople();
            }
            _reply.readException();
            if ((0 != _reply.readInt())) {
                _result = com.czy.server.People.CREATOR.createFromParcel(_reply);
            } else {
                _result = null;
            }
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return _result;
    }

    @Override
    public void addPeople(com.czy.server.People people) throws android.os.RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            if ((people != null)) {
                _data.writeInt(1);
                people.writeToParcel(_data, 0);
            } else {
                _data.writeInt(0);
            }
            boolean _status = mRemote.transact(TRANSACTION_addPeople, _data, _reply, 0);
            if (!_status && IMyAidlInterfaceStubImpl.getDefaultImpl() != null) {
                IMyAidlInterfaceStubImpl.getDefaultImpl().addPeople(people);
                return;
            }
            _reply.readException();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
    }

    public static com.czy.server.IMyAidlInterface sDefaultImpl;
}

最后不要忘了把AIDL文件夹删掉。

发布了65 篇原创文章 · 获赞 24 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/shanshui911587154/article/details/105530128