【问题标题】:Using Intents as a form of message passing使用 Intents 作为消息传递的一种形式
【发布时间】:2014-07-21 23:07:10
【问题描述】:

在我控制的两个应用程序之间使用 Intent 作为一种消息传递形式有什么缺点吗?

我有两个将始终一起存在于设备上的 apk。而且,我想使用显式意图来回传递消息,而不是创建和管理两个单独的服务。使用显式意图似乎比服务更易于管理。

【问题讨论】:

  • 您的具体情况是什么?您的应用程序之间有什么样的交互,是用户级别 (Activity) 还是后台交互?你能解释一下你的问题吗?
  • 如果您是编写这两个应用程序的人,您可以确保将它们视为同一个应用程序,这样它们就可以更轻松地共享数据。这将减少您必须通过意图共享的数据。
  • @StephanBranczyk - 当您说“被视为同一个应用程序”时,您是指将它们设置为使用相同的 userId 吗?清单中设置的 shareUserId 字段?
  • @André.C.S - 交互将在后台进行,即 - UI 中不需要 UI 结果或操作。它严格地来回传递数据。
  • 您不能在不同的应用程序之间使用显式意图。

标签: android android-activity android-service


【解决方案1】:

应用程序之间的通信可以暴露一定的丰富性,但是如果你真的需要这样做,你只能自定义你的应用程序会知道的权限。然后您可以使用BroadcasrReceiver 使用自定义权限安全地交换消息。

定义他们的权限:

<permission android:name="com.yourapp.PERMISSION"
    android:protectionLevel="signature"
        android:label="@string/permission_label"
        android:description="@string/permission_desc">
</permission>

通过设置

<receiver android:name=".MyReceiver"
    android:permission="com.yourapp.PERMISSION">
    <intent-filter>
        <action android:name="com.yourapp.ACTION" />
    </intent-filter>
</receiver>

除了这些权限之外,您还可以将他们的购买设置为ActivitiesServicesContentProvider

已编辑

Android (Inter-Process Communication) 中现有流程之间的集成,AIDL (Android Interface Definition Language)。

AIDL 在不同的应用程序需要时特别有用 他们之间通过交流来交换信息 定义明确的接口,支持多线程。不同于使用 您需要创建的带有 AIDL 绑定服务的 Messenger 一份文件。 AIDL 包含集成接口的声明, 这有助于客户端应用程序知道哪些操作是 可用以及它们各自的参数和返回值。

【讨论】:

  • 广播意图的语义不是特别适合进程间通信。简单地使用 IntentService 并使用 startService 发送意图要好得多
  • @G.BlakeMeike,我同意你的观点,当你说Broadcast 不是这种情况下的最佳选择,但如果我们真的能说出这种情况下的最佳方式, AIDL 无疑是最好的方法,我编辑了我的答案以添加这个技巧。
  • 绑定服务和 AIDL 是强大的工具。它们也有些复杂。对于许多应用程序来说,简单地触发一个 Intent 可能就足够了。
  • @G.BlakeMeike,好吧,我建议你用你的眼光发表你的答案,这样你认为可以进一步帮助你!
【解决方案2】:

您可以使用意图在两个应用程序之间传递数据..但是我发现有一次缺点(不是太大)-您需要注意这些意图不会暴露给其他人。某些恶意应用程序可以使用相同的意图发送类似于拒绝服务攻击的不良数据。

补充一点——如果交互在后台,您也可以使用广播接收器。

此外,如果应用程序总是在一起,为什么不将它们打包为单个应用程序。如果您使用的是 parcelable,如果有两个不同的不兼容版本的 parcelable,您的流程可能会中断。(如果您添加一个字段到一个应用的新版本中的一个对象,另一个应用仍然没有更新,应用可能会崩溃。

【讨论】:

  • 并且通过 Intents 传递数据是一项昂贵的操作,因此请谨慎使用!
  • @rupeshjain - 只是要求它们需要分开,否则会涉及很多不相关的信息。
【解决方案3】:

虽然这里的讨论看起来很不错,但在@André.C.S 的建议下,我会加我的 2 美分。

Intent 是在进程之间传递消息的一种简单而有效的方式。 Android 的主要功能之一,即能够将另一个应用程序作为函数调用 (Activity.startActivityForResult),取决于它。

正如这里的每个人都已经指出的那样,意图,无论是在BroadcastReceiversServices 还是Activities 触发,都存在安全问题。如果您决定使用它们,则需要保护它们。 Andre 对如何使用权限来做到这一点的描述是正确的。您必须将捕获意图的方法视为 Web 服务并相应地验证参数等。

最后,Intents 虽然简单,但确实不适合高带宽 IPC。如果您将以毫秒为单位的速率与其他应用程序交换消息,您将需要查看 AIDL 和绑定服务。根据我的测量,它们的速度要快 1 到 2 个数量级。

顺便说一句,您可以考虑在相同进程中运行这两个应用程序。有清单应用程序属性允许这样做。如果你这样做了,使用显式意图会很容易,你的应用也会更安全。

编辑指出极其尴尬的错误

所以,根据我自己的建议,我尝试了它。令我惊恐的是,正如一些人试图指出的那样,显式意图可以跨进程使用。

我正在吃一大盘乌鸦,甜点是简陋的馅饼。

一个明确的意图包含一个ComponentName 对象,而不是对类对象的明确引用,正如我所声称的。 ComponentName 包含一个包名和一个类名。前者通常是从当前上下文派生的,因此对于当前进程来说是本地的。但是,可以使用任意字符串的包名称构造意图。

我的立场是正确的。

【讨论】:

  • 在我看来,显式意图的整个意图确实是启动一个不同的应用程序。这就是您提供完全限定的包名称的原因。 Dalvik 负责跨流程为您查找是否可行。请参阅这些 SO 问题 - stackoverflow.com/questions/2780102/…stackoverflow.com/questions/6829187/…
  • 是的@SofiaClover 在你尝试之前三天,我编辑了我的答案。它确实工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
相关资源
最近更新 更多