AIDL进阶

2,192 阅读2分钟

Intent传递大数据(仅bitmap有效

Intent.putExtra(String name, Parcelable value)传递大数据时会抛 TransactionTooLargeException异常,可通过 AIDL 使用 Binder实现IPC

 Bundle bundle = new Bundle();
 bundle.putBinder("bitmap", new IMyAidlInterface.Stub() {
    @Override
    public Bitmap getBitMap() {
        return bitmap;
    }
    @Override
    public Person getPerson() throws RemoteException {
        return person;
    }
});
startActivity(new Intent(this, MainActivity.class).putExtra("bundle", bundle));

AIDL中使用自定义对象

1.创建对象并实现Parcelable

package com.xxx.xxx.aidl;
public class Person implements Parcelable {
    ...
    ...
    ...
}

2.创建aidl声明文件Person.aidl

  // Person.aidl
  package com.xxx.xxx.aidl;
  parcelable Person;

3.创建aidl使用文件

// IMyAidlInterface.aidl
package com.xxx.xxx.aidl;

import android.graphics.Bitmap;

import com.xxx.xxx.aidl.Person; //注意

// Declare any non-default types here with import statements

interface IMyAidlInterface {
  Bitmap getBitMap();
  Person getPerson();
}

4.服务端

  Bundle bundle = new Bundle();
        bundle.putBinder("bitmap", new IMyAidlInterface.Stub() {
            @Override
            public Bitmap getBitMap() {
                return bitmap;
            }
            @Override
            public Person getPerson() throws RemoteException {
                return person;
            }
        });

        startActivity(new Intent(this, MainActivity.class).putExtra("bundle", bundle));

5.客户端

 IBinder binder = getIntent().getBundleExtra("bundle").getBinder("bitmap");
        try {
            IMyAidlInterface binder1 = IMyAidlInterface.Stub.asInterface(binder);
            Bitmap bitMap = binder1.getBitMap();
            Person person = binder1.getPerson();
            Log.e("AIDL", "bitmap: " + bitMap);
            Log.e("AIDL", "person: " + person);
            ((ImageView) findViewById(R.id.imageIv)).setImageBitmap(bitMap);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

6.扩转 in out inout 参数修饰

生命周期 (客户端发送数据 - 服务端收到数据 - 处理结束)

1.默认修饰in 客户端发送数据到服务端 服务端修改不会影响客户端

2.out 客户端发送数据到服务端,数据字段内容为空,服务端可修改字段,客户端数据也发生修改

3.inout 客户端发送数据到服务端,数据完整,服务端可修改字段,客户端数据也发生修改

out 时需要手写readFromParcel方法

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(country);
        dest.writeString(town);
    }

	//out 时使用  需要手写
    public void readFromParcel(Parcel dest){
        name = dest.readString();
        country = dest.readString();
        town = dest.readString();
    }

源码分析可以看出

1.in 通过writeToParcel 拷贝客户端数据

2.out 通过readFromParcel获取服务端的数据

3.inout 两者结合


 	/*
      *
      * In生成的函数
      */
      @Override public Person addIn(Person person) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        com.uurobot.yellow.aidl.Person _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          if ((person!=null)) {
            _data.writeInt(1);
            person.writeToParcel(_data, 0);
          }
          else {
            _data.writeInt(0);
          }
          boolean _status = mRemote.transact(Stub.TRANSACTION_addIn, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().addIn(person);
          }
          _reply.readException();
          if ((0!=_reply.readInt())) {
            _result = com.uurobot.yellow.aidl.Person.CREATOR.createFromParcel(_reply);
          }
          else {
            _result = null;
          }
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      
      /*
      *
      *Out生成的函数
      */
      @Override public Person addOut(Person person) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        com.uurobot.yellow.aidl.Person _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          boolean _status = mRemote.transact(Stub.TRANSACTION_addOut, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().addOut(person);
          }
          _reply.readException();
          if ((0!=_reply.readInt())) {
            _result = com.uurobot.yellow.aidl.Person.CREATOR.createFromParcel(_reply);
          }
          else {
            _result = null;
          }
          if ((0!=_reply.readInt())) {
            person.readFromParcel(_reply);
          }
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      
      
      /*
      *
      *In Out生成的函数
      */
      @Override Person addInOut(Person person) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        com.uurobot.yellow.aidl.Person _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          if ((person!=null)) {
            _data.writeInt(1);
            person.writeToParcel(_data, 0);
          }
          else {
            _data.writeInt(0);
          }
          boolean _status = mRemote.transact(Stub.TRANSACTION_addInOut, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().addInOut(person);
          }
          _reply.readException();
          if ((0!=_reply.readInt())) {
            _result = com.uurobot.yellow.aidl.Person.CREATOR.createFromParcel(_reply);
          }
          else {
            _result = null;
          }
          if ((0!=_reply.readInt())) {
            person.readFromParcel(_reply);
          }
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      public static com.uurobot.yellow.aidl.IMyAidlInterface sDefaultImpl;
    }