【问题标题】:How to force stop Intent Service in progress?如何强制停止正在进行的 Intent 服务?
【发布时间】:2013-04-18 22:07:31
【问题描述】:

我有一个可以下载数 GB 视频的 Intent 服务。我有一个“停止”按钮,如果不小心点击“开始”或其他什么,可以停止下载。我知道这已被问过几次,但对我来说没有有效的答案。

我尝试拨打stopService(),但不起作用。那只是调用IntentService.OnDestroy()。 我尝试在onDestroy 中调用stopSelf(),也不起作用。

我尝试使用类似标志的东西,但如果 onHandleIntent 已经运行,它不会被调用,它会等到当前工作完成并执行。即使这会起作用,我也必须有一个像巨大的 if 语句这样的东西,这很糟糕

我唯一的选择真的是将其重写为常规服务吗?

//回答

public class SyncService extends IntentService {

    boolean isCanceled;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent.hasExtra("action")) {

            // Set the canceling flag
            isCanceled= intent.getStringExtra("action").equals("cancel");

        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        // Clean up the possible queue
        if (intent.hasExtra ("action")) {
            boolean cancel = intent.getStringExtra ("action"). Equals ("cancel");
            if (cancel) {
                return;
            }
        }

        ...

        Get your inputStream from HttpUrlConnection or whatever

        ...

        while ((bytesRead = in.read(buffer)) > 0) {
            if (isCanceled) {
                isCanceled = false;
                break;
            }

            ...
        }

    }
}

并触发它

Intent intent = new Intent(context, SyncService.class);
intent.putExtra("action", "cancel");
context.startService(intent);

【问题讨论】:

  • 您可能会考虑从您的问题中删除您的解决方案,而是将其作为解决方案提供。

标签: android service intentservice


【解决方案1】:

我认为你有两个不同的问题:

  1. 如何停止当前下载

  2. 如何停止排队下载,应该在当前下载完成后执行

第一个必须是“类似于标志的东西”,您在下载数据时检查它。否则,没有什么可以阻止您的下载操作。如果您使用的是典型的 HttpUrlConnection 配方,则在循环中检查该标志,您从 HTTP InputStream 读取并写入您的 FileOutputStream。您可以通过调用具有特定Intent 结构的startService() 来设置该标志,将其标识为“取消”操作。您需要在您的IntentService 中覆盖onStartCommand(),查看Intent,如果它是取消Intent,则使用它来设置标志,或者链接到任何其他类型的Intent 的超类。

如果您可能有其他命令排队(场景 #2),您还需要检查 onHandleIntent() 顶部的标志。

【讨论】:

  • 是的,正如你所说。如果我将它重写为服务,我是否能够强制关闭它或者它会和这里一样吗?
  • @VlastoBennyLava:或多或少和这里一样。您可能有更好的能力使用stopService()onDestroy() 来设置标志,但您必须管理自己的后台线程和工作队列。
  • 我用答案伪代码编辑了我的问题,您可能想检查一下。谢谢
  • @VlastoBennyLava:我会使用AtomicBoolean 而不是boolean,因为它将在并行线程上进行操作。否则,应该可以。
【解决方案2】:

鉴于您尚未发布如何准确地处理视频下载,这可能不起作用(在执行下载的onHandleIntent 内会有某种循环)。您可以在IntentService 中使用一个静态类变量来保存下载的停止/开始状态,以便可以通过Activity 设置它。然后,在onHandleIntent 内部,您必须定期检查状态,以便知道何时取消操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 2023-03-24
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多