2013-11-17 3 views
8

Я пытался выяснить эту проблему в течение двух дней, и я полностью запятнал. По какой-то причине я отправляю один запрос в очередь, но залп возвращает его дважды, который дважды вызывает слушателя и удваивает результаты в моем списке. Я включил регистрацию для Volley, и я вижу, что запрос добавляется в очередь и возвращается, а затем через несколько секунд возвращается тот же запрос. Лог нижеAndroid Volley Возвращает результаты дважды за один запрос

V/Volley(14666): [188] CacheDispatcher.run: start new dispatcher 
11-15 12:29:30.152: V/Volley(14666): [1] RequestQueue.add: Request for cacheKey=http://reallylongurl is in flight, putting on hold. 
11-15 12:29:39.722: V/Volley(14666): [1] RequestQueue.finish: Releasing 1 waiting requests for cacheKey=http://reallylongurl. 
11-15 12:29:39.722: D/Volley(14666): [1] MarkerLog.finish: (9809 ms) [ ] http://reallylongurl 0xd68d6603 NORMAL 1 
11-15 12:29:39.732: D/Volley(14666): [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue 
11-15 12:29:39.732: D/Volley(14666): [1] MarkerLog.finish: (+2169) [188] cache-queue-take 
11-15 12:29:39.742: D/Volley(14666): [1] MarkerLog.finish: (+37 ) [188] cache-hit 
11-15 12:29:39.742: D/Volley(14666): [1] MarkerLog.finish: (+6878) [188] cache-hit-parsed 
11-15 12:29:39.742: D/Volley(14666): [1] MarkerLog.finish: (+0 ) [188] post-response 
11-15 12:29:39.752: D/Volley(14666): [1] MarkerLog.finish: (+725) [ 1] done 

A few other requests get queued here. 

11-15 12:29:48.405: D/Volley(14666): [1] MarkerLog.finish: (18302 ms) [ ] http://reallylongurl 0xd68d6603 NORMAL 2 
11-15 12:29:48.412: D/Volley(14666): [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue 
11-15 12:29:48.412: D/Volley(14666): [1] MarkerLog.finish: (+15164) [188] cache-queue-take 
11-15 12:29:48.412: D/Volley(14666): [1] MarkerLog.finish: (+220) [188] cache-hit 
11-15 12:29:48.432: D/Volley(14666): [1] MarkerLog.finish: (+2299) [188] cache-hit-parsed 
11-15 12:29:48.432: D/Volley(14666): [1] MarkerLog.finish: (+0 ) [188] post-response 
11-15 12:29:48.442: D/Volley(14666): [1] MarkerLog.finish: (+619) [ 1] done 

Как вы можете видеть, он никогда не говорит, что добавлен еще один запрос, и он не сказал больше, чем один запрос был в полете. Если я очищу кеш, я получаю тот же результат, только первый запрос - из сети, а второй - из кеша. Я попытался отлаживать и переходить через мой код, но я никогда не вижу, чтобы запрос был помещен в очередь более одного раза. Кто-нибудь видел это раньше? Где бы я ни смотрел?

Благодаря

Edit: Вот код, где пускает залп и где я его называю.

@Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     if (savedInstanceState == null) { 

      TextView emptyView = new TextView(getActivity()); 
      emptyView.setLayoutParams(new LayoutParams(
        LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 
      emptyView.setText("Loading...."); 
      emptyView.setTextSize(20); 
      emptyView.setGravity(Gravity.CENTER_VERTICAL 
        | Gravity.CENTER_HORIZONTAL); 

      ((ViewGroup) mListView.getParent()).addView(emptyView); 
      mListView.setEmptyView(emptyView); 
     } 

     mAdapter = new OttoArrayAdapter(mContext); 
     mListView.setOnScrollListener(onScrollListener); 
     mListView.setAdapter(mAdapter); 

     String url = Util.getURL("", mContext); 

     HttpRequest request = new HttpRequest(url); 
     request.setTag(mContext); 

     VolleyLoader.getInstance(mContext).getRequestQueue().add(request); 

    } 



public class VolleyLoader { 
    private static VolleyLoader mInstance = null; 
    private RequestQueue mRequestQueue; 
    private ImageLoader mImageLoader; 

    private VolleyLoader(Context context) { 

     OkHttpStack stack = new OkHttpStack(); 
     mRequestQueue = Volley.newRequestQueue(context, stack); 
     mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache(
       Util.getCacheSize(context))); 
    } 

    public static VolleyLoader getInstance(Context context) { 
     if (mInstance == null) { 
      mInstance = new VolleyLoader(context); 
     } 
     return mInstance; 
    } 

    public RequestQueue getRequestQueue() { 
     return this.mRequestQueue; 
    } 

    public ImageLoader getImageLoader() { 
     return this.mImageLoader; 
    } 

} 
+0

Можем ли мы увидеть какой-то код, пожалуйста! : D – Necronet

+0

Несомненно, есть определенная часть, которую вам нужно увидеть? Я добавлю, где я создаю очередь и код, который добавляет запрос. – user3001044

+0

У вас есть обычная политика повторных попыток? – Necronet

ответ

5

Я считаю, что я понял это после того, как перешел через код больше. Я считаю, что именно это поведение вызывает softttl. В Volley cachedispatcher

  if (!entry.refreshNeeded()) { 
       // Completely unexpired cache hit. Just deliver the response. 
       mDelivery.postResponse(request, response); 
      } else { 
       // Soft-expired cache hit. We can deliver the cached response, 
       // but we need to also send the request to the network for 
       // refreshing. 
       request.addMarker("cache-hit-refresh-needed"); 
       request.setCacheEntry(entry); 

       // Mark the response as intermediate. 
       response.intermediate = true; 

       // Post the intermediate response back to the user and have 
       // the delivery then forward the request along to the network. 
       mDelivery.postResponse(request, response, new Runnable() { 
        @Override 
        public void run() { 
         try { 
          mNetworkQueue.put(request); 
         } catch (InterruptedException e) { 
          // Not much we can do about this. 
         } 
        } 
       }); 

Это сообщение ответ затем отправляет его в сеть, сообщения другого ответ на тот же слушатель.

+0

Нашел это, прежде чем видеть это сообщение. Был поиск способа игнорировать кеш и использовать свежие данные, если, конечно, загрузка не удалась (без Интернета и т. Д.) –

+0

@ Losin'Me Привет, Вы нашли какое-либо решение? Я столкнулся с той же проблемой. Можете ли вы добавить ответ здесь? –

+0

У нас есть метод загрузки, который использует bool «useCache», если true проверит кеш для данного URL-адреса. Если запись кэша существует, мы проверяем, истек ли срок ее действия, если мы ее не используем, иначе мы создадим новый запрос с помощью 'setShouldCache (false)'. Единственное, что нам нужно сделать, - это сделать наш собственный элемент Request, который расширяет Request, но держится за его запись Cache и передает ее через прослушиватель, чтобы мы могли поместить ее в кеш, когда запрос был успешным. –

0

Чтобы остановить множественный запрос, вы можете настроить политику повтора для объекта запроса с помощью метода setRetryPolicy() объекта запроса. Мне удалось сделать это с помощью следующего кода:

req.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 0, 
     DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 

С выше коде, я сократил время ожидания до 2 секунд и установить число повторных попыток 0.

Смежные вопросы