【问题标题】:Android StartActivtyForResult() from a Service来自服务的 Android StartActivtyForResult()
【发布时间】:2011-10-04 23:36:19
【问题描述】:

首先我很抱歉我的英语不太好:)。

我在开发我的应用时遇到了问题。

这是我的解决方案的通用架构方案。

http://i.stack.imgur.com/ooTmE.png

为了快速,应用程序必须对代码进行解码,但有两种可能的方式:

  1. 使用外部设备(构造函数提供了一个包含 android Service 的 sdk 来与设备通信),
  2. 通过 Zxing 库使用手机摄像头,可以有意识地对其进行管理。

我自己的服务的目标是管理一些业务代码并使用户对工具的选择透明化。

我认为这是一个很好的解决方案,但我想实施它并且遇到了不同的问题。

我的主要问题是我无法在服务内执行 StartActivityForResult。

是否有人对我的问题有任何建议,无论是架构更改还是主要问题的解决方案?


@Laurent':你完全正确,我的服务充当 API 适配器。

我会尽量让预期的行为更清晰。

我有一个应用程序需要识别顶部有二维码的(真实)对象。在应用程序的生命周期内,用户将多次执行此识别操作。

用户选择通过单击按钮来启动识别(或其他方式,但他知道识别将开始)。所以不需要通知。

问题是他没有选择进行识别的方式。这就是为什么,正如你所说,我实现了一个适配器。

适配器选择:

相机移动或外部设备。第一个是来自 Zxing 库的活动。第二个是管理外部设备的服务。该服务提供了一个返回结果的接口。

还有一件事,我需要我的整个实现(适配器和 co)可以被其他需要识别的应用重用。

所以我的想法是实现一个服务作为适配器来回答我的两个条件(使用户的选择透明 - 并使识别可用于其他应用程序)。

希望你能理解我的问题。

【问题讨论】:

    标签: android architecture android-service


    【解决方案1】:

    鉴于您的架构,您的MyOwnService 必须充当 API 适配器:它应该提供统一的扫描 API 并透明地处理每个外部服务的特殊性。

    您的预期行为不够明确,无法提供适合您需求的解决方案,但这里有一些说明可能会有所帮助。

    被动扫描:

    • 即使有一些解决方法:不应从服务启动任何活动(而不是直接)。绝不。坏的。服务是后台的东西,他们最多允许提示用户Notifications(这是贾斯汀优秀答案的第 2 点)。

    因此,没有任何“弹出活动”(这很好!)。如果您需要连续扫描条形码,即使您的活动没有运行,那么警告用户的唯一方法是使用状态栏通知。

    主动扫描:

    • 在您自己的活动中,您可以bind 到您的包装服务并使其开始扫描代码栏。当它找到一个时,它必须message您的活动。您的 Activity message handler 拥有对 UI 的完全访问权限,可以将您的发现通知用户。

    您在编辑中选择了主动扫描,因此您的问题是找到一种方法让您的服务主动通知您的主应用程序(开始主动扫描的那个) 新项目已成功扫描。

    您不能通过启动新活动来执行此操作(记住:这很糟糕),但您可以 bind 到服务和/或在包装服务和应用程序之间使用 Messages

    我建议您花时间阅读(并花更多时间理解)this android developer article on BoundServices,尤其是关于Messengers 的部分。

    Service 和 Activity 之间的双向消息传递的完整示例可以在以下 android 示例中找到:Service & Activity

    警告:设计稳健、成熟的基于 AIDL 的服务是一项艰巨的工作。

    【讨论】:

    • 您完全正确,我的服务充当 API 适配器。我将尝试使预期的行为更加清晰。我有一个应用程序需要识别顶部有二维码的(真实)对象。在应用程序的生命周期中,用户将多次执行此识别操作。用户选择通过单击按钮来启动识别(或其他方式但他知道识别将开始)。所以不需要通知。问题是他没有选择进行识别的方式。这就是为什么,正如你所说,我实现了一个适配器。 [...下一条评论]
    • [PREVIOUS COMMENT...]适配器选择:相机移动或外部设备。第一个是来自 Zxing 库的活动。第二个是管理外部设备的服务。该服务提供了一个接口来获取结果。还有一件事,我需要我的整个实现(适配器和 co)可以被其他需要识别的应用程序重用。所以我的想法是实现一个服务作为适配器来回答我的两个条件(使用户的选择透明 - 并使识别可用于其他应用程序)。我希望我更清楚
    • 谢谢,我会阅读关于有界服务的文章。只是我已经将mainActivity绑定到服务上来管理服务的某些部分,比如startScan或者getDeviceStatus。但是我想让服务里面的识别的所有业务部分很好的分离识别部分的MainApp。但这似乎很难。我将阅读这篇文章并在之后回来:) 感谢您的时间和您对我的问题的兴趣。
    【解决方案2】:

    有两种方法可以解决这个问题。

    1) 让 MyOwnService 对 MainActivity 进行回调,告诉它启动您的 ScanActivity。 - 如果 MyOwnService 的任务仅在 MainActivity 运行时运行并且用户希望 ScanActivity 自动出现,这是一种更好的方法。

    2) 让 MyOwnService 创建一个通知,让用户访问 ScanActivity。 - 如果 MyOwnService 的任务运行时间可能比 MainActivity 的生命周期长,这是一个更好的方法。这样一来,您就可以毫不掩饰地让用户知道他们可能想要访问 ScanActivity。

    【讨论】:

    • 我的选择是第一种方式,因为服务不应该在我的 mainActivity 生命周期之外发送通知。但事情是,我发现主活动启动服务然后服务有点奇怪,如果它选择移动相机进行扫描,则必须回调主活动......在我看来,我期望所有业务代码都将保留在服务中......我不确定我是否足够清楚
    • 我希望所有有关扫描和识别的代码都将保留在服务和它需要的其他应用程序中......
    • 我可以理解您的担忧,但您也说您的业务代码涉及操作 UI,这不应该是这种情况。业务代码应该将一个事件发布回 UI,以便它可以决定如何最好地调出 ScanActivity。至少我是这么看的。
    • 嗨贾斯汀,我的业务代码没有修改我的 UI,或者如果它修改了,由于我自己的服务接口,它是通过回调来实现的。 (使用 bindService())。问题是启动使用相机进行扫描的活动。正如我在上面试图解释的那样。我想将服务用作适配器,并使此适配器在应用程序的整个生命周期内可用,并可用于其他应用程序。但也许服务的选择不是好的选择......说实话我迷失在android架构中......
    • 我的意思是,通过让您的服务启动一个活动,它通过使其出现来修改 UI。如果您想将 MainActivity 与您想要启动的 ScanActivity 隔离开来,我建议您将回调中的 Intent 传递回主要活动。这样,所有主要活动都需要使用您的服务提供的意图调用 startActivity。这应该足以让事情分开。
    【解决方案3】:

    所以最后我改变了我的架构。

    我选择删除 myOwnService 并创建一个中间活动作为我的 API 适配器。

    此活动将有一个 dialog.theme 看起来像一个对话框,指示正在执行识别。

    如果识别使用外部设备,此活动将停留在前台,否则相机活动将启动(由中间活动管理)。

    感谢我可以管理来自中间活动的结果,并且没有奇怪的 android 架构,将我的业务代码保留在我的主应用程序之外。

    服务不是很好的选择。

    非常感谢您的帮助和您的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多