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

使用显式与隐式意图启动android服务,android,android-intent,intentfilter,implicit,explicit,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); // Using

根据标准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>
您还可以使用隐式意图和清单中指定的操作字符串启动/停止服务,如下所示:

// 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>
//使用隐式意图:
静态最终字符串serviceAction=“com.example.my.app.services.MYSERVICE”;
意向serviceIntent=新意向(serviceAction);
startService(serviceIntent);
//AndroidManifest.xml:
当服务仅在本地使用时(不允许第三方应用程序启动或绑定到该服务),文档说明不应在清单服务标记中包含意图过滤器,并且应将导出的标记设置为false


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

我的问题是:

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

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

问题是,当资源不足时,Android可以并且将很容易地破坏:应用程序进程,只要:服务进程继续运行,这对我来说是好的。 (是的,我知道将服务设置为前台服务会影响流程,等等。我也可以阅读手册;)但这不是我的问题)

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


欢迎任何专家级建议

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

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


服务在做什么?

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

让我在这里列出一些事实

  • “已启动”服务(而不是“绑定”服务)的生命周期独立于已启动此服务的活动的生命周期。无论两者是否在同一进程中运行,这都是正确的
  • 在任何时间点,只有一个服务实例处于活动状态。当您的活动调用startService()时,如果服务实例尚未运行,则将创建该实例(在这种情况下,您的服务也将收到onCreate()回调)。但若服务已经在运行,那个么框架只需对已经在运行的进程调用onStartCommand()回调(在本例中并没有onCreate()回调)。同样,无论活动和服务在同一进程或不同进程上运行,所有这些都是正确的
现在回答您的问题,如果您的服务仍然在运行(因为前面的活动调用了startService()),那么bindService()/startService()将确保连接到现有的服务


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

“注意:活动和服务在单独的流程中运行(:应用程序和:服务流程)”--请不要再问了。它是不需要的,使你的应用程序更复杂,浪费内存,浪费CPU/电池等@Commonware谢谢你的建议,我正在考虑。但是问题呢,这些问题还没有解决。嗨,只是为了回答你的“如果发现任何问题,请告诉我”。当您使用隐式意图时,您使用的是服务的显式实现(或者……实际上是接口)。这意味着您不能选择自己的实现(您应该更改代码来实现)。