gpt4 book ai didi

android - 通过 AIDL 在服务之间传递 Activity 对象

转载 作者:太空宇宙 更新时间:2023-11-03 10:23:00 24 4
gpt4 key购买 nike

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

例如,服务 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 传递我的对象(扩展 Binder )来实现此目的,但没有任何效果,当我尝试从方法 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 接口(interface),您可以通过该接口(interface)将此“自定义对象”作为包裹传递。不要那样做。相反:
  • 您传递的对象本身应该由 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");

但是我认为,如果您让一切都变得顺畅,您的生活会更加理智。

类分享注意事项

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

关于android - 通过 AIDL 在服务之间传递 Activity 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16767907/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com