【问题标题】:Android volley is sending information twice with image uploadAndroid volley 正在通过图像上传两次发送信息
【发布时间】:2013-11-29 10:28:10
【问题描述】:

我正在尝试将带有我的帖子数据的图像从 android 发送到我的服务器。为了实现这一点,我将我的图像进行了 base 64 编码为字符串,并使用 android volley 库将其发送。但是,这会引起问题。出于某种原因,它有时会发送两次帖子,我不知道为什么。下面是调用来发送发布请求的函数。我在String url = "http://domain.com/ajax_ws.php"; 上打了一个中断标记,然后在protected Map<String, String> getParams() { 上打了一个我发现String url = ... 只被调用一次,但是当它发送两个时,protected Map... 被调用了两次。我在 android volley 上找不到任何文档,所以我不知道为什么会这样。位图已调整大小,因此图像字符串始终介于 100k 和 200k 个字符之间。我想这可能是一个大小问题,但我的服务器正在接收图像并解码它们,一切都很好。

 public void Sharing() {

    pd = ProgressDialog.show(getParent(), null, "Please Wait...");
    final String caption = mEtMessage.getText().toString();
    RequestQueue queue = Volley.newRequestQueue(this);
    String url = "http://domain.com/ajax_ws.php";
    StringRequest postRequest = new StringRequest(
            Request.Method.POST,
            url,
            new MyStringListener(),
            new MyErrorListener()
    ) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("token", "secretToken");
            params.put("mode", "createVoucher");
            params.put("user_id", ActivityLogin.id);
            params.put("deal_id", ActivitySharing.id_deal);
            params.put("user_id_company", ActivityRestaurantDetails.res.getId());
            params.put("user_img", pathImage);
            params.put("caption", caption);
            params.put("company_id", ActivityRestaurantDetails.res.getId());
            return params;

        }
    };
    queue.add(postRequest);
}

知道为什么会发生这种情况吗?

【问题讨论】:

  • 只是一个建议:最好将匿名Response.Listener 提取到分离(内部?)类以简化事情并使您的代码更具可读性。它现在非常混乱,并且使您的一半屏幕被缩进覆盖。
  • @Secator 谢谢,我会这样做的,这段代码已经被绞尽脑汁,到处都是。
  • 我正面临着确切的问题。我的进一步调查表明它可以处理任何慢速连接。我尝试调试 Volley 库,发现双重发布是由方法“performRequest(Request> request)”中的 BasicNetwork 类中的 SocketTimeoutException 引起的。每次引发异常时,都会发生双重发布。不幸的是,我对此没有任何解决方案。让我知道你的想法。而且,我认为这与 RetryPolicy 无关。您在 RetryPolicy 上添加的任何数字都不会影响修复此问题。
  • @user2848783 您是否设法找到解决此问题的方法?阻止它多次发布?
  • @jfry22 我实施了一个变通方案,它并不理想,但运行良好。我在通过 WS 调用发送的 android 上生成一个随机字符串。在我们的服务器上调用该函数之前,它会检查该随机字符串在过去一小时内是否存在于日志表中。如果它不存在,则随机字符串存储在带有时间戳的表中,并且函数执行。如果它确实存在,这意味着调用是一个重复请求并且它退出。不是最干净的,但它可以完成工作。

标签: php android android-volley


【解决方案1】:

将重试次数编辑为 1。它对我有用。

stringRequest.setRetryPolicy(new
          DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, 1, 
                           DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)
                );

【讨论】:

    【解决方案2】:

    试试这个。

    JsonObjectRequest jsonObjRequest = new JsonObjectRequest(...);
    jsonObjRequest.setRetryPolicy(new DefaultRetryPolicy(0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    

    【讨论】:

      【解决方案3】:

      解决方案是编辑重试策略,此处也有说明:(http://www.techstricks.com/avoid-multiple-requests-when-using-volley/)。

      但是,如果覆盖对您不起作用,那么您可能希望重新访问您的 volley 缓存逻辑。由于 volley 缓存中的软 ttl,结果从缓存中传递,同时它将另一个网络请求排队,该请求也将返回结果。因此,一个请求但有两个不同的结果。

      【讨论】:

        【解决方案4】:

        以下修复对我有用。那些使用 HTTPS 和 volley 的人应该试试这个。

        DefaultRetryPolicy  retryPolicy = new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
                jsr.setRetryPolicy(retryPolicy);
        

        希望这能帮助您解决问题。

        【讨论】:

        • 谢谢。你的帮助很大。 DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);最终请求队列 requestQueuetnn = Volley.newRequestQueue(Activity.this,hurlStacktnn); requestQueuetnn.add(stringRequesttnn); stringRequesttnn.setRetryPolicy(retryPolicy);
        【解决方案5】:

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

        首先由 Snicolas 建议。更改了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());

        希望对你有帮助:)

        【讨论】:

          【解决方案6】:

          Volley 使用 RetryPolicy 处理请求,默认情况下使用指数退避算法发送请求最多 3 次。可能是某些请求失败并被重试吗?第一次调用请求时是否收到任何错误/成功日志?

          【讨论】:

          • 你是对的。我做了一些进一步的测试,它发生在更大的图像上。但是,这会产生另一个问题,那就是如何处理这个问题。我有一些想法,但缺乏这方面的经验,所以我发布了另一个问题here谢谢您的回复!
          • 要了解重试策略,请参考这个Retry Policy.Retry Policy`包含3个参数RequestTimeOut,Retries,Multiplier.RequestTimeOutVolley库等待Http响应的时间.在此期间,如果没有响应,则返回相同的Http request。重试次数根据Retriesvalue 进行。如果Retry Policy =1,当Request TimeOut被超过时,同样的Http request只会产生一次。
          猜你喜欢
          • 1970-01-01
          • 2013-11-29
          • 1970-01-01
          • 2015-10-27
          • 1970-01-01
          • 1970-01-01
          • 2017-01-25
          • 2019-09-22
          • 1970-01-01
          相关资源
          最近更新 更多