10

根据标准 Android 文档,启动服务(即已启动服务)的首选方式是使用如下显式意图:

// Using explicit intent:
Intent serviceIntent = new Intent(getApplicationContext(), MyService.class);
// or:
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);

您还可以使用带有清单中指定的操作字符串的隐式意图来启动/停止服务,如下所示:

// Using implicit intent:
static final String serviceAction = "com.example.my.app.services.MYSERVICE";
Intent serviceIntent = new Intent(serviceAction);
startService(serviceIntent);

// AndroidManifest.xml:
<service android:name="com.example.my.app.services.MyService"
   android:exported="false" android:process=":services" >
   <intent-filter>
      <!-- Start/Stop service -->
      <action android:name="com.example.my.app.services.MYSERVICE" />
   </intent-filter>
</service>

当服务仅在本地使用时(不允许第三方应用程序启动或绑定到它),文档说您不应该在清单服务标签中包含意图过滤器,并且应该将导出的标签设置为 false。

注意:活动和服务在不同的进程中运行(:应用程序和:服务进程)。活动和服务之间的通信是通过实现 AIDL 接口来完成的(这样做是因为只有 AIDL 远程接口允许我在需要同时处理 IPC 的服务内进行多线程处理,不仅在活动之间,而且主要在运行于内部的服务之间:服务流程)。

我的问题是:

Q1:当我在我的应用程序中使用的活动和服务在两个不同的进程中运行时,我是否需要使用隐式意图而不是显式意图来启动和停止服务?

Q2:当 :application 进程消失(已销毁,不再在内存中)并且 :services 进程在后台运行时,如何从新的 :application 进程再次连接到已经运行的 :services 进程?不知何故,我需要再次获得对 :services 进程的引用,以便我可以停止该进程中正在运行的服务。使用 AIDL afaik 无法做到这一点。

问题是Android可以并且将在资源不足时轻松破坏 :application 进程,只要 :services 进程继续运行,我就可以了。(是的,我知道通过将服务设置为前台服务等来影响流程。我也可以阅读手册;)但这不是我的问题)。

当活动和服务位于单独的进程中并使用 AIDL 时,以及当 :application 进程需要在被 Android 杀死后再次“找到” :services 进程或当用户再次进入应用程序(在他/她之前离开应用程序之后)。

欢迎任何专家级的建议。

4

2 回答 2

9

A1:即使您的活动和服务在不同的进程中运行,它们仍然属于同一个应用程序。您仍然可以使用显式意图,我在这里看不到使用隐式意图的任何具体优势(如果找到任何内容,请告诉我:))

A2:让我在这里列出几个事实

  • “Started”服务(而不是“Bind”ed服务)的生命周期独立于启动该服务的Activity的生命周期。无论两者是否在同一个进程中运行,这都是正确的。
  • 在任何时间点,只有一个 Service 实例处于活动状态。当您的活动调用 startService() 时,如果服务实例尚未运行,则将创建它(在这种情况下,您的服务也会收到 onCreate() 回调)。但是如果 Service 已经在运行,Framework 会简单地在已经运行的进程上调用 onStartCommand() 回调(在这种情况下没有 onCreate() 回调)。同样,无论活动和服务是在同一进程或不同进程上运行,所有这些都是真实的。

现在回答您的问题,如果您的服务仍在运行(由于先前活动的 startService() 调用),那么 bindService()/startService() 将确保连接到现有服务。

希望这对您有所帮助。如果您有任何其他具体问题,请告诉我。

于 2013-11-20T13:11:18.833 回答
0

您无需使用隐式意图在单独的流程中启动服务或活动;但是,为 Activity 使用单独的进程是一种罕见的情况。为服务使用单独的进程更为常见,但我还是想知道用例是什么。

如果您的应用程序进程被破坏然后重新启动,您将使用 startService 重新连接到服务。如果服务正在运行,则连接到它,否则将重新启动服务。如果您想终止该服务,您可以终止它,或者您可以从您的主应用程序运行 stopService()。

服务在做什么?

于 2013-09-20T23:23:44.040 回答