android - 使用 Parcelable 是在应用程序之间发送数据的正确方法吗?

标签 android marshalling unmarshalling parcelable multiple-processes

我试图了解如何在 Android 中的应用程序之间进行通信 - 而不仅仅是在 Activity 实例之间进行通信。

我设置了一个“客户端”,将 Messenger obj 发送到服务(在发送到服务的 Intent 中);该服务创建一个 Message obj,并使用 messenger.send(message) 将其发送回“客户端”。在我尝试使用 Message.obj 保存对象之前,这一切正常。

我在服务中创建了自己的ParcelableMyParcelable,并放入消息中。一切正常,直到消息在“客户端”中被解码。解码失败,因为“客户端”无权访问 MyParcelable 类。这很明显 - 它们位于不同的包中(比如 com.whatever.myclientcom.whatever.myserver)。这是完全错误的做法吗?

我也试过创建一个 Parcel 并发送它(两个应用程序都可以访问该类) - 但 Parcel 不是 Parcelable。我已经阅读了有关正在使用的类加载器的信息,但不了解如何在单独的应用程序中分离类加载器(进程,如果我在这方面了解 Android 体系结构)。也就是说,一个类加载器如何“教授”另一个类加载器中存在的类?看起来应该有一个明显的“你就是这样做的”,但我还没有看到。

最佳答案

您不能在不知道此类的进程中解码一个类(正如您已经正确指出的那样)。如果您希望将 MyParcelable 发送到您的 Service,那么您需要在构建时将 MyParcelable 包含在 Service 中, and 包括正确的 ClassLoader 在解码时使用,因为解码是由系统线程完成的,它不知道 MyParcelable 是什么即使您在编译时包含它。

编辑:

(a) include MyParcelable into 2 different pkgs and have them be seen as the same class

创建一个通用类库并将其包含在两个应用程序(应用程序和服务)中。您可以将其标记为 Android 库(在 Eclipse 中,它位于项目的 Android 属性下)或将其导出为 JAR 并在两个应用程序中导入。在库中拥有独立类而不是直接将它们放在应用程序中总是一个好主意。这样您就可以在其他项目中重用它们 ;)

(2) include the right ClassLoader (where do I get the right class loader from, for example)

您可以在执行代码时从当前线程获取您的ClassLoader。显然这个 ClassLoader 知道你的类,因为它正在执行你的代码 ;) 例如在 Activity#onCreate() 中,你可以做 Thread.currentThread.getContextClassLoader() 。由于您的 MyParcelable 类也包含在 Service 中,您可以执行相同的操作来获取有效的 ClassLoader 以进行解码。

IPC 的另一个解决方案是定义一个 AIDL interface所以你不必实现 Parcelable

关于android - 使用 Parcelable 是在应用程序之间发送数据的正确方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15606460/

相关文章:

android - 如何在 Chrome(ARC Welder)上捕获在 Android Runtime 上运行的 Android 应用程序日志?

android - 如何读取assets中的excel文件?

c# - PInvoke 和 char**

xml - GoLang XML编码(marshal)处理自定义(无根元素的编码(marshal))

c# - 将 HBITMAP 句柄从非托管代码传递到托管代码以创建 System.Drawing.Bitmap 的安全性

java - Android 上的 SimpleXML 和反序列化时出错

android - 无法将 json 格式的字符串转换为 Java 映射

java - BluetoothSocket isConnected() 函数在运行时导致 java.lang.NoSuchMethodError

java - 通用列表的 DynamoDBMarshaller

java - JAX-WS 如何在 HTTP 字符串被解码之前拦截它