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

use*_*342 10 android explicit implicit intentfilter android-intent

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

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

您还可以使用带有清单中指定的操作字符串的隐式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>
Run Code Online (Sandbox Code Playgroud)

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

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

我的问题是:

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

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

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

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

欢迎任何专家级的建议.

San*_*osh 8

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

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

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

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

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