5

我已经工作Android了一年多,但我仍然无法确定何时应该在进程/线程之间使用不同类型的消息传递/通信。我主要说的是广播Intents,使用AIDL for services,使用Handlers发送消息和socket通信。

其中许多工具可用于完成类似的任务,但哪种工具更适合特定情况?

4

4 回答 4

16

这是一个非常开放的问题,但让我来描述一下我如何看待应用程序内/应用程序间的通信效果最好。

Android 消息传递的关键方面之一是所有应用程序组件都松散绑定的概念。因为所有应用程序都在一个单独的进程中运行,并且一个“应用程序”实际上可能包含多个应用程序(负责提供不同的活动或服务),所以消息传递技术都基于跨进程边界编组消息的想法。

意图

消息传递的首选技术,总是尽可能尝试使用 Intent。这是在 Android 中传输消息的最“原生”方式。

好处

使用 Intent 进行消息传递可以保持应用程序组件的松散绑定,让您可以在多个应用程序之间无缝传输消息。Intent 在核心系统中被大量使用来启动活动和服务,以及广播和接收系统事件。

使用 extras Bundles,您可以在 Intents 中包含键/值对作为有效负载数据,以便轻松地将信息从一个应用程序组件传递到另一个应用程序组件 - 即使这些组件在不同的进程中运行。

缺点

因为 Intent 被设计为在进程之间传递,所以 extras 有效负载仅支持原始类型。如果您需要使用 Intent 发送对象,则需要在一端将其解构为基元,并在另一端对其进行重构。

应用类

如果您只想在单个进程中运行的单个应用程序中进行通信,这是一个方便的解决方案。

好处

通过扩展Application类(并将其实现为单例),您将获得一个对象,该对象将在任何应用程序组件存在时都存在,从而提供一个集中的位置来存储和在应用程序组件之间传输复杂的对象数据。

缺点

这种技术将您的消息传递限制在单个应用程序中的组件上。

服务绑定、IPC 和 AIDL

绑定到服务允许您访问其方法并与之交换对象。AIDL 是一种定义如何将对象序列化为 OS 原语的方法,以便如果您绑定到的服务在单独的应用程序中运行,它可以跨进程边界编组。

好处

当您绑定到服务时,您可以访问它,就好像它是调用类中的对象一样。这意味着您可以在服务上执行方法并与之交换丰富的对象。

请注意,如果您在不同的应用程序进程中绑定到服务,则需要创建 AIDL 定义来告诉 Android 如何序列化/反序列化您想要在应用程序之间传递的任何对象。

缺点

为 IPC 创建 AIDL 类需要一些额外的工作,并且绑定会在服务和活动之间创建额外的依赖关系,这会使内核在其他应用程序处于饥饿状态时更难清理资源。

但是,跨进程边界对消息进行编组是昂贵的。因此,如果您没有在服务上执行方法,使用绑定和 IPC 可能是矫枉过正 - 看看您是否可以使用 Intents 实现相同的目标。

插座

如果您使用套接字在单个设备上运行的应用程序内部或之间进行通信,那可能是因为没有其他方法,或者您在某个地方错过了一个技巧。如果您的消息正在离开设备,那么套接字是一个很好、快速的替代方案。如果您留在设备上,Intents 或 IPC 将是一个更好的选择。

于 2009-06-03T21:44:17.277 回答
2

这完全取决于您的应用程序的用例和类型。如果应用程序一直在运行,则最好使用 AIDL 方法,因为它是最安全的通信方式。如果应用程序不需要一直运行,那么您可以使用广播意图或待处理意图方法在应用程序之间进行通信。

于 2015-06-09T14:36:14.180 回答
1

我的 2 美分

  • 我没有使用本地套接字。似乎有点矫枉过正,因为您必须生成和解析数据。
  • 意图是针对其他应用程序可能想要做的事情(在撰写窗口中启动我或挑选一些东西)
  • AIDL/Parcels/Handlers 用于让 GUI 与不断运行的无头进程对话。根据应用程序,许多实际数据传输可能会使用内容提供程序进行,但我倾向于有一些数据需要在该通道之外传输。
于 2009-05-29T18:05:35.667 回答
0

这是一篇很好的文章,我发现它有助于寻找 Cocoa 的 NSUserDefaults 类的替代品:

http://developer.android.com/guide/appendix/faq/framework.html

于 2010-10-16T01:34:33.200 回答