Android - 取消 Volley 请求

17

我在我的项目中使用Android Volley库来执行网络请求,一切都很顺利,但是我在这个库的“取消”功能方面遇到了一些麻烦。我解释一下我的问题...

我有一个活动,在OnCreate方法中执行请求,请求被调用,没有问题。但为了确保cancel方法可以正常工作,我想尝试测试两件事:

  1. 我发起请求后立即取消它,像这样:

    MySingleton.getMyData("urltocall", getDataListener, requestTag); MySingleton.getRequestQueue().cancelAll(requestTag);

这个方法可以正常工作!取消已经被调用(我也可以在Volley的Request类中看到它):

public void cancel() {
        mCanceled = true; // my breakpoint is called here
    }
  1. 我发送了请求,然后在我的活动的onDestroy和/或onStop方法中调用相同的代码:

    MySingleton.getMyData("urltocall", getDataListener, requestTag); MySingleton.getRequestQueue().cancelAll(requestTag);

但是这个方法不起作用

requestTag不为null,并已传递给Volley,所以我不明白为什么第一个方法可以工作而另一个方法不能... 我的目的是在调用onDestroy时取消请求...

谢谢您的帮助

4个回答

21
我猜测在第一种情况下,请求只被添加到了RequestQueue中,这就是为什么调用cancelAll()会起作用的原因。在第二种情况下,在开始请求和暂停/销毁Activity之间存在轻微延迟:在那个延迟期间,HTTP请求已经开始。您可能不知道,调用cancelAll()仅适用于仍在RequestQueue中的那些请求。对于已经开始的HTTP请求,它不起作用,没有办法停止它。
话虽如此,这里的文档暗示,一旦取消请求(即通过调用cancel()),可以将其视为从未调用过该Web服务一样有效处理。与特定请求相关联的回调将不会被调用(尽管接收到的响应可能会保存在本地缓存中)。

谢谢 Zygoteinit! 所以,取消当前请求是不可能的,但是取消未来挂起的请求是可能的,对吧?这就是你所说的 HTTP 请求行为。 - ejay
2
是的,由于明显的原因(一旦开始网络调用必须完成),无法取消已经开始的请求。只有那些仍在“RequestQueue”中的请求可以被停止,因为它们尚未开始。我希望您能理解这一点。 - Yash Sampat
是的,我理解这个原因,只是很遗憾它可能会导致内存泄漏。谢谢你的回复 ;) - ejay
@Y.S. 我遇到了棘手的问题。假设我开始了Volley请求,然后突然退出了我的应用程序。这导致我在退出应用程序后遇到了“NullPointerException”。我认为片段应该随其活动一起退出。但即使如此,Volley请求仍然保持活动状态,并在到达“ErrorListener”时将nullpointer抛出到我的“Toast”中。请帮忙。我被卡住了。 - Roon13
@Roon13:抱歉,这篇帖子…… :) - Yash Sampat
显示剩余4条评论

8
您可以取消与标签TAG相关联的Request。因此,您必须为每个Request添加一个标签。 yourRequestObject.setTag(TAG); RequestQueue mRequestQueue; mRequestQueue.cancelAll(TAG); 通过这种方式,您可以取消所有特定TAGRequest

7

https://developer.android.com/training/volley/simple.html#cancel

这篇文章的意思是:

Volley保证一旦取消,不会调用响应处理程序。

所以,即使没有办法撤销/取消已经开始的http请求(这是有道理的),与请求相关联的回调也不会被调用,这对我来说在大多数情况下都可以将其视为已取消的请求,尽管因此接收到的响应可能已经悄悄地存储在缓存中。


1
我建议您在onPause()方法中取消添加的请求。 考虑到:
onPause()系统首先调用此方法,表示用户正在离开您的活动(尽管这并不总是意味着活动正在被销毁)。 这通常是您应该提交任何应该持久存在于当前用户会话之外的更改的地方(因为用户可能不会回来)。来源:Android Developers

嗨,安迪,谢谢你的回复,但是在onPause()中尝试仍然存在问题。我认为ZygoteInit关于HTTP请求行为的说法是正确的,一旦请求被发送,就无法取消它,但对于队列中的其他等待请求则可以取消。 - ejay
1
嗨 :) 当然他是对的,我是指你可以在onPause而不是onStop中调用你的待处理请求函数,因为我想你可能想保存一些相关信息 :) - Andy
确实,在onPause()中取消操作可以保存一些有用的数据。 ;) - ejay
@Julien 我在 Activity 类中声明了 onResponse()。我应该在 onResponse 方法中检查 this == null 吗? - ARK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接