7

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

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

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

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

4

3 回答 3

3

您不能在不了解此类的进程中解组该类(正如您已经正确指出的那样)。如果你想MyParcelable被发送到你的Service,那么你需要MyParcelableService构建时包含,并且包含ClassLoader在解组时使用的权利,因为解组是由系统线程完成的,它不知道什么MyParcelable,因为解组是由系统线程完成的,即使你包含它是什么在编译时。

编辑

(a) 将 MyParcelable 包含到 2 个不同的 pkg 中,并将它们视为同一类

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

(2) 包括正确的类加载器(例如,我从哪里获得正确的类加载器)

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

IPC 的另一个解决方案是定义一个AIDL 接口,这样您就不必实现Parcelable.

于 2013-03-25T02:43:31.550 回答
1

如果您不想在某处使用持久层(我使用云 API),您可以在单独的进程中运行服务并将需要共享值持有者类型对象数据的相应应用程序绑定到该服务。该服务将是您代表连接(绑定)应用程序构建和获取 obj 值的地方。

于 2013-03-25T02:58:07.430 回答
1

好的,我找到了我正在寻找的“简单方法”。您可以将 Bundle 放入 Message.obj 字段中。Bundle 是 Parcelable 的,因此可以在客户端和服务器之间传输。服务器不知道它正在接收什么类是没有问题的,因为 Bundle 是“内置”到 Android Java 中的。并且 Bundle 显然可以在 in 中包含“子捆绑包”。这比确保双方都知道用户定义类的定义要简单。感谢上面的答案 - 我当然很感激这些信息!

于 2013-03-28T03:44:19.130 回答