【问题标题】:Waiting requests functionality issue within Volley library (PriorityBlockingQueue.java)Volley 库 (PriorityBlockingQueue.java) 中的等待请求功能问题
【发布时间】:2015-12-22 09:20:38
【问题描述】:

我对 volley 库中的等待请求功能有疑问。调试将我带到 java.util 中的 AbstractQueue 类,其中正在添加一个元素(根据方法中指示成功添加到队列的某些值)并且同时 - 未添加(根据队列中的 0 个元素- 不会改变它们的价值)。添加方法是同步的。您可以在下面找到有关情况的详细描述以及我迄今为止的研究。如果您查看它们并分享您是否知道正在发生的事情,我将非常感激。

我尝试在出现任何类型的错误时自动重试请求(例如 - 当没有连接或服务器名称不正确时)。 请求的错误处理程序将请求添加回我的应用的静态单例 RequestQueue。

RetriableRequestWraper.java

m_request = new StringRequest(
            method,
            url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    handleResponse(response);
                }
            },

            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {
                    handleError(volleyError);
                }
            });

public void handleError(VolleyError volleyError)
{
    Log.d("Request: ", m_request.toString());
    Log.d("handleError: ", volleyError.toString());
    if(retriesCount<3)
    {
        executeRequest();
        ++retriesCount;
    }
    else
    {
        retriesCount = 0;
    }
}

public void executeRequest()
{
    RequestsManager.getInstance().executeRequest(m_request);
}

public void executeRequest(Request request)
{
    Log.d("executeRequest ","m_requestQueue.add(request)");
    m_requestQueue.add(request);
}

RequestManager.java

public void executeRequest(Request request)
{
    Log.d("executeRequest ","m_requestQueue.add(request)");
    m_requestQueue.add(request);
}

这种方法不起作用,并且在 volley 库中进行调试时,我发现请求无法添加到 RequestQueue 类的 mCacheQueue 中,因为 mWaitingRequests 映射中存在 reuqest 的 cacheKey。因此请求被添加到 mWaitingRequests 映射中的队列中,对应于它的键。当上一个请求完成时 - 新请求不会添加到队列中,尽管这些行正在 RequestQueue 类中执行:

synchronized(this.mWaitingRequests) {
            String cacheKey1 = request.getCacheKey();
            Queue waitingRequests1 = (Queue)this.mWaitingRequests.remove(cacheKey1);
            if(waitingRequests1 != null) {
                if(VolleyLog.DEBUG) {
                    VolleyLog.v("Releasing %d waiting requests for cacheKey=%s.", new Object[]{Integer.valueOf(waitingRequests1.size()), cacheKey1});
                }

                this.mCacheQueue.addAll(waitingRequests1);
            }
        }

当进一步调试这一行时

this.mCacheQueue.addAll(waitingRequests1);

在 AbstractQueue.java(java.util 中的类)中,元素被添加到队列中,“modified”值为真,但在整个空洞时间,“this”参数继续包含 0 个元素。

    public boolean addAll(Collection<? extends E> c) {
    if (c == null)
        throw new NullPointerException("c == null");
    if (c == this)
        throw new IllegalArgumentException("c == this");
    boolean modified = false;
    for (E e : c)
        if (add(e))
            modified = true;
    return modified;
}

在 PriorityBlockingQueue.java 的 offer(E e) 方法中,程序的执行在第 453 行停止。

l452 siftUpUsingComparator(n, e, array, cmp);
l453 size = n+1;

显然返回值为true,但没有添加元素。我的调试器无法进入添加元素的方法 - siftUpUsingComparator(n, e, array, cmp);

我将在重试我的请求之前添加一个计时器,并将构建一个新的计时器。所以我对解决方法并不感兴趣,我想了解在这种情况下发生了什么以及如何发生。您知道这背后的原因是什么吗?

【问题讨论】:

    标签: java android android-volley


    【解决方案1】:

    问题是您尝试再次将相同的请求实例添加到它已添加到的队列中。这会弄乱队列和请求本身,因为它有状态。例如,如果您只是启用标记,您将遇到崩溃。解决方案是仅使用默认重试策略或克隆请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多