android – 通过AIDL在服务之间传递活动对象

我正在尝试为不同包中的多个服务共享一个公共对象.每个服务必须调用同一个对象.

例如,服务A(来自APK A)实例化自定义对象,我希望服务B和C(来自APK B和C)检索此对象的引用并调用它的某些方法.

我在Android参考中发现应该可以使用Parcel

Active Objects

An unusual feature of Parcel is the ability to read and write active
objects. For these objects the actual contents of the object is not
written, rather a special token referencing the object is written.
When reading the object back from the Parcel, you do not get a new
instance of the object, but rather a handle that operates on the exact
same object that was originally written. There are two forms of active
objects available.

Binder objects are a core facility of Android’s general cross-process
communication system. The IBinder interface describes an abstract
protocol with a Binder object. Any such interface can be written in to
a Parcel, and upon reading you will receive either the original object
implementing that interface or a special proxy implementation that
communicates calls back to the original object. The methods to use are
writeStrongBinder(IBinder), writeStrongInterface(IInterface),
readStrongBinder(), writeBinderArray(IBinder[]),
readBinderArray(IBinder[]), createBinderArray(),
writeBinderList(List), readBinderList(List), createBinderArrayList().

我尝试通过传递我的对象(扩展绑定器)通过AIDL但没有任何作用来做到这一点,当我尝试从方法createFromParcel(Parcel in)中检索引用时,我总是得到一个ClassCastException.

我的代码示例:

public class CustomObject extends Binder implements Parcelable {

  public CustomObject() {
    super();
  }

  public static final Parcelable.Creator<CustomObject> CREATOR = new Parcelable.Creator<CustomObject>() {
  public CustomObject createFromParcel(Parcel in) {
    IBinder i = in.readStrongBinder();
      // HOW TO RETRIEVE THE REFERENCE ??
      return null;
    }

    @Override
    public CustomObject[] newArray(int size) {
      return null;
    }
  };

  @Override
  public int describeContents() {
    return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeStrongBinder(this);
  }
}

有人已经这样做了吗?

提前致谢 !

最佳答案 这有两种方法.

简单:对象本身使用aidl

>您似乎有一个现有的AIDL接口,您可以通过该接口将此“自定义对象”作为一个包传递.不要那样做.代替:
>您传递的对象本身应由AIDL描述.比方说,例如,您将其称为ICustomObject.aidl.
>在这种情况下,您不需要使对象Parcelable.你可能甚至不需要编写上面的代码;只需在另一个中使用一种AIDL描述的类型.例如,将这样的行添加到服务A的主AIDL:

ICustomObject getCustomObject();

>在服务A中,在你已经拥有的Stub类中,你需要简单地返回从ICustomObject继承的东西.
>在服务B和C中,您可以简单地调用该方法来获取ICustomObject.简单!没有包裹,没有readStrongBinder(),没有.

更难

如果您执行上述操作,则Android工具链会生成Java代码,该代码会对对象进行编组和解组.你可以自己编写代码.

ICustomObject myObjectWhichActuallyLivesInAnotherProcess = ICustomObject.Stub.asInterface(parcel.readStrongBinder())

甚至

ICustomObject myObjectWhichActuallyLivesInAnotherProcess = (ICustomObject)parcel.readStrongBinder().queryLocalInterface("com.your.custom.object");

但是我觉得如果你把所有东西都做出来,你的生活会更加清醒.

关于课堂分享的说明

您可能想要创建一个Android“库项目”,其中包含ICustomObject.aidl,这样您就可以在构建A,B和C的项目之间共享结果类.

点赞