【问题标题】:Android remote Service start and stopAndroid远程服务启动和停止
【发布时间】:2012-12-20 03:35:20
【问题描述】:

我正在开发一个应用程序来异步调用服务器以获取通知。在主要活动中一切正常。现在困扰我的是,我需要一个服务,当应用程序不活动时会轮询通知(就像 GMail 股票应用程序一样)。因此,我在主要活动 onStop 函数中的另一个进程中启动远程服务,如下所示:

@Override
public void onStop() {
    super.onStop();
    if(prefs.getBoolean(OPTIONS_KEY_SERVICE, false)) {
        startServiceIntent = new Intent(CloudAlarmsService.MY_SERVICE);
        Bundle b = new Bundle();
        b.putStringArray("duidCodes", duidCodes);
        startServiceIntent.putExtras(b);
        Log.d("SSE_SERVICE", "Starting Service");
        startService(startServiceIntent);
    }
}

它工作正常,我在活动关闭后收到通知。现在我想在活动开始时停止远程服务(所以我不会同时有活动和服务轮询服务器)。我是这样做的:

@Override
public void onResume() {
    super.onResume();
    stopService(new Intent(CloudAlarmsService.MY_SERVICE));
    Log.d("SSE_SERVICE", "Stopping service");
}

CloudAlarmsService.MY_SERVICE 是我的服务类中的一个字符串:

public class CloudAlarmsService extends Service {
    public static String MY_SERVICE = "cloudindustries.alarms.service.BACKGROUND_SERVICE";
...

并且它也在清单 xml 中声明如下:

<service android:process=":alarms_poller" android:name=".CloudAlarmsService">
     <intent-filter android:label="@string/serviceStopService">
           <action android:name="cloudindustries.alarms.service.BACKGROUND_SERVICE" />
     </intent-filter>
</service>

但是服务并没有停止,它一直在工作。在我关闭主要活动后,会产生另一个服务实例并继续轮询。

我有什么遗漏的吗? 或者这对于远程服务来说可能是一个不好的用途,或者甚至还有另一种类型的服务/管理器可以用于这种目的?

感谢您的帮助!

编辑:

问题澄清:是否可以从不同的活动(没有启动服务)停止远程服务?

【问题讨论】:

  • onStartCommand 返回什么?粘? (但不确定您是否可以从与启动它的实例不同的实例停止服务)
  • 不,不是 STICKY,我打算在我找到一种方法在不同的情况下停止它时返回粘性。
  • 你确定它已经停止了吗?
  • 为什么要分进程运行?
  • @RokasJurevicius :我的意思是在停止服务之前尝试停止所有计时器并尝试停止您的服务Intent intent = new Intent();intent.setClass(getApplicationContext(), CloudAlarmsService.class); getApplicationContext().stopService(intent);

标签: android service


【解决方案1】:

尝试停止CloudAlarmsService服务为:

Intent intent = new Intent();
intent.setClass(getApplicationContext(), CloudAlarmsService.class); 
getApplicationContext().stopService(intent);

【讨论】:

  • 我觉得第一个版本更简洁。第二个函数可能会在代码中带来一些混乱..
  • @RokasJurevicius :是的,你是对的,但是当我们想要使用动作来启动/停止 ActivitySerivce 或任何其他应用程序组件时,我们需要发送完全合格的意图
  • 如果您明确指定组件(您在第一个示例中使用 CloudAlarmsService.class 以及在第二个示例中使用 setComponent()setClassName() 执行此操作,则没有意图解析 继续。您正在绕过 Intent 解析过程(当您仅指定 ACTION 时会发生这种情况,因为 OP 在他对 startService()stopService() 的原始调用中所做的那样)。我想要得到什么在于它应该可以停止服务显式设置组件。当然,我也可能错了。
  • 您关于使用 action 启动/停止... 的评论不正确。当 OP 启动服务时,他使用一些随机字符串作为 Intent ACTION,没有别的。 Intent Resolution 发生,Android 试图找到一个合适的 Service 组件,该组件具有与此 ACTION 匹配的 IntentFilter。它找到一个(他的服务)并启动它。 Intent ACTION 字段不用于指定“开始”或“停止”,这是在框架本身中完成的。
  • 通常有可以解释的原因导致意图解析不起作用。我也看到了这些问题。如果您查看 SDK 附带的 Android 示例代码,在 /ApiDemos/src/com/example/android/apis/app/RemoteService.java 中,您可以看到它们仅使用 ACTION 字符串(就像 OP 正在做的那样)。