目前我正在片段中的停止方法中使用mRequestQueue.cancelAll(getActivity()),但显然当我将手机从横向移动到肖像时,它仍然会返回请求中生成的数据但导致崩溃,因为数据剂量的持有者已经存在。任何正确的代码示例代码?
答案 0 :(得分:56)
不要使用cancelAll的标签,而是使用全通RequestFilter。
mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
@Override
public boolean apply(Request<?> request) {
return true;
}
});
编辑:这将取消所有活动/片段的所有请求,并且不能与活动生命周期一起使用。管理此方法的最佳方法是添加片段唯一的String标记。
答案 1 :(得分:18)
您应该将标记设置为对象,而不是方法。
通过将标记设置为getActivity()
,您要求Volley在主线程上使用动态方法调用作为对后台线程上发生的请求的引用。
因此,当后台线程试图取消请求时,活动可能已经死了。
使用getActivity()
或其他一些对象或字符串,而不是使用this
。
这是任何标记的好习惯,您还应该注意 leaking your activity.
<强>解决方案:强>
您可以使用当前对象:
request.setTag(this);
或,静态类对象
request.setTag(MyFragment.class);
或者,作为一个单独的类中的常量:
request.setTag(CustomTags.LIST_REQUESTS);
CustomTags.LIST_REQUESTS在我看来是最好的(泄漏活动的可能性更小)
这样的事情:
public class CustomTags
{
public static final String LIST_REQUESTS="CustomTags:LIST_REQUESTS";
}
<强>更新强>
我刚注意到我在Volley中标记我的请求时犯了一个错误(尽管上面发布的解决方案很好)。
我仍然认为我会在这里更新一个要记住的重要事项。排球标记为身份而不是值。
因此,重要的是要记住,只是相同字符串值的标记,而不是同一个对象本身,将不会被识别为相同的tag
。
它类似于
之间的区别String a1 = "A";
String a2 = "A";
a1 == a2; //evaluates to false
String a1 = "A";
String a2 = "A";
a1.equals(a2); // evaluates to true
答案 2 :(得分:4)
我知道这个答案来得晚,但万一有其他人遇到这个问题:
在我的实现中,标记在请求被添加到队列的位置被设置(并被覆盖)。
尽管我使用我的Tag取消了请求,但请求队列上的标记不一样(之前被覆盖)并且没有被取消。
记录正在运行的请求并打印出标签,引导我找到解决方案:
mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
@Override
public boolean apply(Request<?> request) {
Log.d("DEBUG","request running: "+request.getTag().toString());
return true;
}
});
答案 3 :(得分:3)
您在提出请求时使用了哪个标记?如果您没有在每个请求上设置标记,那么它可能永远不会有效。据我所知,Volley不会自动为您的请求设置标签
答案 4 :(得分:0)
如果您从片段添加队列请求,则应取消如下:mRequestQueue.cancelAll(this)
。抱歉,如果它不起作用 - 我没有测试这个解决方案。但我希望对你有所帮助。
答案 5 :(得分:0)
您是否正在为活动设置请求标记?这是您提供的代码的唯一方式。 cancelAll方法使用您提供的任何标记的标记搜索所有请求并取消它们。
答案 6 :(得分:0)
查看这篇文章。它使用Oto作为单例事件总线。这样,您可以在重新创建活动或片段时通知排列队列。您当然可以使用普通的旧接口来监听更改。作为一个统一的解决方案,BUt Otto看起来不那么冗长和优雅。
http://andraskindler.com/blog/2013/eventbus-in-android-an-otto-example/
答案 7 :(得分:0)
在碎片的情况下;
仅使用一个
RequestQueue rQueue;
在OnCreate method;
初始化
并将其用于所有截击请求;
最后
@覆盖
public void onStop () {
super.onStop();
if (rQueue != null) {
rQueue.cancelAll(this);
}
}
答案 8 :(得分:0)
在科特林
requestQueue?.cancelAll { true }
答案 9 :(得分:-1)
我一直在努力解决内存泄漏问题,直到发现我从'RequestQueue'类调用了stop()。
import random
import time
import os
def cls():
os.system('cls' if os.name=='nt' else 'clear')
randomnumber = random.randint(6,16)
block = []
printed = []
health = 10
blocks = "\x1b[1;37;48m#"
randumplace = random.randint(0, len(block))
multiplier = 47
def build(blocks):
for i in range (multiplier):
block.append(blocks)
printed.append(blocks)
i = random.randrange(1, 75)
if i == 4:
blocks = "\x1b[1;31;48mM"
elif i == 15:
blocks = "\x1b[1;36;48m~"
elif i == 25:
blocks = "\x1b[1;36;48m~"
elif i == 22:
blocks = "\x1b[1;33;48m$"
elif i == 1:
blocks = "\x1b[1;37;48m#"
elif i == 10 and "@" not in printed:
blocks = "@"
else:
blocks = "\x1b[1;37;48m."
counter = 1
print("# "+"# # # # # #" + " #" * (multiplier - 6))
while counter != randomnumber:
del block[:]
build(blocks)
print(*block)
counter += 1
print ("" + "# " * (multiplier +1))
position = printed.index("@")
while position != 38:
movement = input("Move which direction? (Type 'help' for commands)")
if movement == "d":
cls()
printed.pop(position+1)
printed.insert(position+1, "@")
printed.pop(position)
printed.insert(position, ".")
print(*printed)
position = printed.index("@")
if movement == "a":
cls()
printed.pop(position-1)
printed.insert(position-1, "@")
printed.pop(position)
printed.insert(position, ".")
print(*printed)
position = printed.index("@")
if movement == "w":
cls()
printed.pop(position-32)
printed.insert(position-32, "@")
printed.pop(position)
printed.insert(position, ".")
print(*printed)
position = printed.index("@")
if movement == "s":
cls()
printed.pop(position+33)
printed.insert(position+33, "@")
printed.pop(position)
printed.insert(position, ".")
print(*printed)
position = printed.index("@")
该类说“停止缓存和网络调度程序”。意味着什么...