我正在尝试了解如何在Android中的应用程序之间进行通信 - 而不仅仅是Activity
个实例之间的通信。
我设置了一个“客户端”,它将一个Messenger obj发送给一个服务(在发送给服务的Intent
中);该服务创建Message
obj并使用messenger.send(message)
将其发送回“客户”。这很好用,直到我尝试使用Message.obj来保存一个对象。
我在服务中创建了自己的Parcelable
类MyParcelable
并将其放入邮件中。一切都有效,直到消息在“客户端”中被解组。 unmarshall失败,因为'client'无法访问MyParcelable
类。这很明显 - 它们位于不同的包中(比如com.whatever.myclient
和com.whatever.myserver
)。这完全是错误的做法吗?
我还尝试创建Parcel
并发送(因此两个应用程序都可以访问该类) - 但Parcel
不是Parcelable
。我已经阅读过关于正在使用的类加载器,但是不了解单独的应用程序中的单独的类加载器(进程,如果我在这方面理解Android架构)。也就是说,如何对一个类加载器“教授”另一个类加载器中存在的类?当然看起来应该有一个显而易见的“这就是你如何做到”,但我还没有看到它。
答案 0 :(得分:2)
你不能在一个不知道这个类的进程中解组一个类(正如你已经正确指出的那样)。如果您希望将MyParcelable
发送到Service
,那么您需要在MyParcelable
的构建中包含Service
,和包含权限解组时要使用ClassLoader
,因为解组是由系统线程完成的,即使你在编译时包含它,它也不知道MyParcelable
是什么。
修改:
(a)将MyParcelable包含在2个不同的pkgs中并让它们被看到 作为同一个班级
创建一个公共类库,并将其包含在两个应用程序中(应用程序和Service
)。您可以将其标记为Android库(在Eclipse中,它位于项目的Android属性下)或将其导出为JAR并将其导入两个应用程序。在库中使用独立的类而不是直接将它们放在应用程序中总是一个好主意。这样您就可以在其他项目中重复使用它们;)
(2)包括正确的ClassLoader(我在哪里获得正确的类 例如,装载机
您可以在执行代码时从当前线程中获取ClassLoader
。显然,ClassLoader
知道您的类,因为它正在执行您的代码;)例如,在Activity#onCreate()
中,您可以执行Thread.currentThread.getContextClassLoader()
。由于您MyParcelable
课程也包含在Service
中,因此您也可以这样做以获得有效的ClassLoader
解组。
IPC的另一个解决方案是定义AIDL interface,这样您就不必实施Parcelable
。
答案 1 :(得分:1)
如果您不想在某处使用持久层(我使用云API),您可以在单独的进程中运行服务,并将需要共享值持有者类型对象数据的相应应用程序绑定到服务。该服务将是您构建的位置,并代表连接(绑定)应用程序获取obj值。
答案 2 :(得分:1)
好的,我找到了我想要的'简单方法'。您可以将Bundle放入Message.obj字段中。 Bundle是Parcelable,因此可以在客户端和服务器之间传输。服务器不知道它接收了什么类,因为Bundle“内置于”Android Java中。 Bundle显然可以包含'sub-Bundles'。这比必须处理确保双方都知道用户定义类的定义更简单。感谢上面的答案 - 我当然感谢信息!