2013-11-15 1 views
9

Я пытаюсь отправить изображение с моими данными на мой сервер с android. Для этого я основал 64, закодировал мое изображение в строку и отправил его с помощью библиотеки андроидных залпов. Это вызывает проблемы. По какой-то причине он иногда отправляет сообщение дважды, и я не могу понять, почему. Ниже приведена функция, которая вызывается для отправки запроса на отправку. Я положил знак разрыва на String url = "http://domain.com/ajax_ws.php";, а затем один на protected Map<String, String> getParams() {. Я нашел String url = ... только один раз, но когда он отправляет два, protected Map... вызывается дважды. Я не могу найти документацию по андроидному залпу, поэтому я не знаю, почему это происходит. Растровое изображение изменяется, поэтому строка изображения находится где-то между 100 и 200 тыс. Символов. Я подумал, что это проблема размера, но мой сервер получает изображения и расшифровывает их, и все просто отлично.Android volley отправляет информацию дважды с загрузкой изображения

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); 
} 

Любая идея, почему это может произойти?

+0

Только предложение: Было бы хорошо, чтобы извлечь анонимный 'Response.Listener' отделить (внутренний?) Класс, чтобы упростить вещи и сделать код более читаемым. Это довольно захламлено прямо сейчас, и половина экрана покрыта отступом. –

+0

@ Secator Спасибо, я сделаю это, этот код прошел через режущий инструмент, он повсюду. – tomjung

+0

Я столкнулся с точной проблемой. Мое дальнейшее исследование показывает, что оно связано с любым медленным соединением. Я попытался отладить библиотеку Volley и нашел шаблон, который двойной поступок вызван SocketTimeoutException в классе BasicNetwork в методе «performRequest (Request request)». Каждый раз, когда возникает исключение, происходит двойное сообщение. К сожалению, для этого я не получил никакого решения. Дайте мне знать вашу мысль. А также, я не вижу, что это связано с RetryPolicy. Любое число, которое вы положили на RetryPolicy, не повлияет на исправление этого. –

ответ

4

Volley использует RetryPolicy для обработки запросов, которые по умолчанию отправляют запрос до 3 раз с помощью экспоненциального алгоритма отсрочки. Может быть, какой-то запрос терпит неудачу и повторится? Получаете ли вы журналы ошибок/успехов для первого вызова запроса?

+0

Вы правы. Я провел некоторое дополнительное тестирование, и это происходит с большим изображением. Это создает еще одну проблему, и именно так можно справиться с этой проблемой. У меня есть некоторые идеи, но у меня нет опыта в этой области, поэтому я разместил еще один вопрос [здесь] (http://stackoverflow.com/questions/20011775/sending-image-via-android-volley-with-php) Спасибо вы за свой ответ! – tomjung

+0

Чтобы понять политику повтора, см. Эту [Retry Policy] (https://github.com/smanikandan14/Volley-demo) '.'Retry Policy' содержит 3 параметра' RequestTimeOut, Retries, Multiplier'.'RequestTimeOut' является время, когда библиотека 'Volley' ждет ответа« Http ». В течение этого времени, если ответа нет, он делает тот же «запрос Http». Количество попыток выполняется в соответствии с значением «Retries». Если 'Retry Policy = 1', и когда' Request TimeOut' превышен, он делает один и тот же «запрос Http» только один раз. – laaptu

7

Я могу решить эту проблему двумя способами.

Первый предложен Snicolas. Изменен RetryPolicy. Просто установите значение тайм-аута в два раза по умолчанию. Отлично. Вы также можете попробовать другие значения.

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

Другой способ заключается в установке connection.setChunkedStreamingMode(0); в openConnection методе HurlStack класса.

Я создаю мой RequestQueue как этот requestQueue = Volley.newRequestQueue(context, new HurlStack());

Надеется, что это помогает :)

3

Ниже затруднительное работал для меня. Те, кто работает с HTTPS и залпом, должны попробовать это.

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

Надеюсь, что это поможет вам решить проблему.

6

Резолюция предназначена для редактирования политики повтора, которая также поясняется здесь: (http://www.techstricks.com/avoid-multiple-requests-when-using-volley/).

Однако, если переопределение не работает для вас тогда, вам может потребоваться пересмотреть логику кэширования волейбола. Из-за мягкого ttl в кэллинге волей результата результат доставляется из кеша и в то же время он ставит в очередь другой сетевой запрос, который также вернет результат. И, следовательно, один запрос, но два разных результата.

1

Попробуйте этот.

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

отредактируйте номер повтора до 1. он работал для меня.

stringRequest.setRetryPolicy(new 
      DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, 1, 
          DefaultRetryPolicy.DEFAULT_BACKOFF_MULT) 
       ); 
Смежные вопросы