【问题标题】:Android Volley double post when have slow request请求缓慢时的Android Volley双发
【发布时间】:2014-04-21 02:55:57
【问题描述】:

我在慢速网络上遇到 Volley POST 请求问题。每次我在 LogCat 中看到 BasicNetwork.logSlowRequests 时,我的 POST 请求都会执行两次或更多次,从而导致 1 个请求的多个(2 个或更多)张贴。我已经将重试策略设置为 0,但它没有帮助。

这是我的 LogCat

03-16 01:31:35.674: D/Volley(5984): [19807] BasicNetwork.logSlowRequests:请求的 HTTP 响应=http://[myserver]/api/places 0xfa7d0c33 正常 1> [寿命=3824], [大小=313],[rc=200],[retryCount=0] 03-16 01:31:35.704: D/Volley(5984): [1] Request.finish: 3853 ms: [] http://[myserver]/api/places 0xfa7d0c33 正常 1

这是我的代码

JSONObject body = new JSONObject();
try {
    body.put(PROTO_BODY_AUTHORIZATION, Sessions.getActiveSession().getToken());
} catch (JSONException e) {
    e.printStackTrace();
}

JsonObjectRequest request = new JsonObjectRequest(
        Request.Method.POST,
        context.getResources().getString(R.string.server_address) + "/places",
        body,
        callback,
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context, error.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
);

request.setRetryPolicy(
        new DefaultRetryPolicy(
                DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
                0,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    getRequestQueue().add(request);

请帮忙,我正在拼命寻找这个问题的解决方案。

【问题讨论】:

  • 您的网络请求超时秒数是否与重试策略超时秒数相同?
  • 网络请求超时量在哪里获取?如果我从 LogCat 中看到,请求生命周期是 3825 毫秒。重试策略超时量为 2500ms (DefaultRetryPolicy.DEFAULT_TIMEOUT_MS)
  • 如果我查看Volley 的源代码,我看到大多数超时设置为 5000 毫秒。我猜你的帖子是双重的,因为你的重试发生在请求超时之前,实际上发送了两次。
  • 已在本次讨论中解决stackoverflow.com/questions/47936955/…

标签: android android-volley


【解决方案1】:

将以下值添加到您的请求对象:

request.setRetryPolicy(new DefaultRetryPolicy(
    DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2,
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

这里: request 是您的 JsonObjectRequest 对象。根据 Volley 中 DefaultRetryPolicy 类中的 DEFAULT TIMEOUT VALUE 更改 multiplicator 的值。

您也可以将第一个参数设置为 0,如下所示:

request.setRetryPolicy(new DefaultRetryPolicy(
    0,
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

【讨论】:

  • 仍然重复..帮助??
  • 您可以将默认缓存设置为 false
  • request.setRetryPolicy(new DefaultRetryPolicy(0,0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));使:DefaultRetryPolicy.DEFAULT_MAX_RETRIES 为 0
  • 您的第二个答案将第一个值设置为 0,解决了我的问题.. 谢谢队友。
  • 这肯定不适用于我的代码!应用该解决方案 3 个月,但不!不工作!截至今天,我仍然面临这个问题!
【解决方案2】:

只是将 RetryPolicy 中的 Timeout 设置为 0 太少了。 检查源后,您必须实际设置最大重试次数

我通过将政策设置为以下来修复重复发布

new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

【讨论】:

  • 我相信这是正确的答案。虽然你也可以设置超时值
【解决方案3】:

我找到了双发的解决方案,我只是将超时设置为0。

【讨论】:

  • 您能详细说明一下吗?将超时设置为 0 可能会导致更多请求被触发,对吧?
  • 显然没有,似乎 0 表示没有超时。正如我所发现的,如果凌空达到超时,它将触发另一个请求。因此将超时设置为 0 可以防止 volley 触发另一个请求。
  • 对此我不太确定。我刚刚将超时时间增加到 30000 毫秒,以暂时延迟事情。
  • 这是一个非常糟糕的解决方案,在我的情况下,启动活动向服务器发送一个发布请求,当用户没有互联网时,发布请求永远不会失败并且用户被阻止,我认为 Droid_Mechanic 的答案更好。
【解决方案4】:

我找到了多帖子错误的解决方案。

更改重试策略。 我将超时值设置为 50000 毫秒,工作正常 像这样:

  request.setRetryPolicy(
                new DefaultRetryPolicy(
                        500000,
                        DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
                )
        );

【讨论】:

    【解决方案5】:

    您必须将 RetryPolicy 设置为 0 次重试,并确保超时大于服务器超时。

    setRetryPolicy(new DefaultRetryPolicy("bigger than server timeout",
                                          0,
                                          DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    

    【讨论】:

      【解决方案6】:

      我可以通过两种方式解决这个问题。

      首先更改为RetryPolicy。 只需将超时值设置为默认超时的两倍。工作得很好。您也可以尝试其他值。

      request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
      

      另一种方法是在openConnection 方法HurlStack 类中设置connection.setChunkedStreamingMode(0);

      我正在创建我的RequestQueue 像这样requestQueue = Volley.newRequestQueue(context, new HurlStack());

      希望对你有帮助:)

      【讨论】:

      • 我们如何在openConnection方法HurlStack类中设置connection.setChunkedStreamingMode(0);?我试图扩展HurlStack 但失败了。我也尝试了您的第一个解决方案,但没有成功。
      • 在您的 Volley 库项目中,您可以在工具箱包中看到 HurlStack。第一个解决方案应该可行,尝试使用不同的超时值。
      • 是的,我确实看到了 HurlStack 类,但我找不到任何方法来放置 connection.setChunkedStreamingMode(0);。你能发布一些演示代码吗?关于第一个解决方案,我尝试了所有情况,包括更改超时,将重试更改为 0 和 System.setProperty("http.keepAlive", "false"),但它仍然不起作用。
      【解决方案7】:

      请增加 setRetryPolicy 时间。

      request.setRetryPolicy(new DefaultRetryPolicy(
                          30000,
                          DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                          DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
                  Volley.newRequestQueue(this).add(equest);
      

      【讨论】:

        【解决方案8】:

        我让双重请求停止的唯一方法是将重试策略重试次数设置为 -1

        request.setRetryPolicy(new DefaultRetryPolicy(0, -1, 0));
        

        我认为这是因为如果在 hasAttemptRemaining() 方法中 retryCount 为 0 并且 Max retries 也为 0,则 DefaultRetryPolicy 的剩余尝试逻辑返回 true:

        protected boolean hasAttemptRemaining() {
            return this.mCurrentRetryCount <= this.mMaxNumRetries;
        }
        

        【讨论】:

          【解决方案9】:

          这对我有用。

          public class MyRetryPolicyWithoutRetry implements RetryPolicy
          {
              @override
              public int getCurrentTimeout()
              {
                  return CONNECTION_TIME_OUT; /200000/
              }
          
              @Override
              public int getCurrentRetryCount()
              {
                  return 0;
              }
          
              @Override
              public void retry(VolleyError error) throws VolleyError
              {
                  throw(error);
              }
          }
          

          使用方法:

          request.setRetryPolicy(new MyRetryPolicyWithoutRetry());
          

          【讨论】:

            【解决方案10】:

            我在这里问了一个类似的问题:

            Android Volley makes 2 requests to the server when retry policy is set to 0

            我设法通过在 Android 中将 keep-alive 属性设置为 false 来解决这个问题,例如:

            System.setProperty("http.keepAlive", "false")
            

            我在导入请求队列并发出请求的类中添加了这行代码。

            另外,检查您的服务器是否有 keep-alive 标头。

            这个post 帮助找到了解决方案。

            【讨论】:

              【解决方案11】:

              是超时错误的问题 请求执行了两次,所以你有一个 double 值

              尝试使用此代码增加超时错误请求:

              request.setRetryPolicy(new DefaultRetryPolicy(
              DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2,
              DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
              DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
              

              【讨论】:

                【解决方案12】:

                我设法通过像这样配置 HttpURLConnection 来解决这个问题:

                connection.setChunkedStreamingMode(0);
                

                我在 Volley 电子邮件列表 (https://groups.google.com/forum/#!topic/volley-users/8PE9dBbD6iA) 中开始讨论这个问题。

                【讨论】:

                • 您是否在HurlStack.java 文件中添加了行?
                • 是的,我将它添加到 openConnection() - HttpURLConnection 正在初始化的方法中。
                【解决方案13】:

                群发请求政策仅一次请求以避免重复发布

                我尝试了这个解决方案,但不起作用

                //...........solution 01
                jsonObjectRequest.retryPolicy = DefaultRetryPolicy(
                120000, 
                0,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)
                
                
                or
                
                //...........solution 02
                jsonObjectRequest.retryPolicy = DefaultRetryPolicy(
                0, 
                -1,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)
                
                
                MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest)
                

                完整源代码:https://androidkeynotes.blogspot.com/2020/02/volley.html

                【讨论】:

                  【解决方案14】:

                  只是maxNumRetries = 0 没有工作。 set TIMEOUT_MS 20000.

                  request.setRetryPolicy(new DefaultRetryPolicy(20000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
                  

                  【讨论】:

                  • 你能解释一下你的意思吗?
                  【解决方案15】:
                  request.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
                  

                  这对我有用。

                  【讨论】:

                    【解决方案16】:

                    更正android date 解决了我的问题,不幸的是,出于测试目的,我更改了我的 android 日期并出现 ssl 安全错误。

                    【讨论】:

                      【解决方案17】:

                      尝试了很多东西,但最终没有任何帮助。最后,我想出了以下变化组合:

                      sr.setRetryPolicy(new DefaultRetryPolicy(0,-1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
                      

                      并在应用程序类的 hurl 连接中添加:

                      httpsURLConnection.setChunkedStreamingMode(0);
                      

                      这很顺利地阻止了 Volley 在服务器上遇到多个请求。

                      【讨论】:

                        【解决方案18】:

                        最佳解决方案:

                        jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(0, 
                             DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
                        

                        为我工作。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2013-07-06
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2017-10-27
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多