使用显式vs隐式意图启动android服务

时间:2013-09-20 19:42:23

标签: android android-intent intentfilter implicit explicit

根据标准的Android文档,启动服务(启动服务)的首选方法是使用这样的显式意图:

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

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

// 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>

当服务仅在本地使用时(不允许第三方应用程序启动或绑定它),文档说您不应在清单中包含 intent-filter service 标记,您应将导出的标记设置为false。

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

我的问题是:

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

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

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

当活动和服务处于独立进程并使用AIDL时,我无法找到与我的问题相关的任何信息或答案,以及:当应用程序进程需要在Android被杀死后再次“找到”:服务进程时或者当用户再次进入应用程序时(之后他/她离开应用程序)。

欢迎任何专家级建议。

2 个答案:

答案 0 :(得分:8)

A1:即使您的活动和服务在不同的流程中运行,它们仍属于同一个应用程序。你仍然可以使用显式意图,我没有看到在这里使用隐式意图的任何特定优势(让我知道如果找到任何:))

A2:让我在这里列出一些事实

  • “已启动”服务的生命周期(而不是“绑定”服务)与启动此服务的Activity的生命周期无关。无论天气如何都在相同的过程或不同的过程中运行,情况都是如此
  • 任何时间点只有一个服务实例存活。当您的活动调用startService()时,如果服务实例尚未运行,则将创建该服务实例(在这种情况下,您的服务也将接收onCreate()回调)。但是如果Service已经在运行,那么Framework只会在已经运行的进程上调用onStartCommand()回调(在这种情况下,没有onCreate()回调)。无论活动和服务是在相同的流程还是不同的流程上运行,所有这一切都是如此。

现在回答你的问题,如果你的服务仍在运行(因为前一个活动的startService()调用),那么bindService()/ startService()将确保连接到现有服务。

希望这对你有所帮助。如果您有任何其他具体问题,请与我们联系。

答案 1 :(得分:0)

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

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

服务在做什么?