2016-12-10 2 views
0

Я получаю места с Картами Google и модифицирую их и добавляю их в список. Я хочу собрать все места в списке, я сделал это как внизу, но allItem размер списка всегда возвращается 0, я не могу понять, почему, я что-то упустил ?. Может кто-нибудь мне помочь?Android - размер ArrayList всегда возвращается 0

Мой Глобалы

ArrayList<MapData.ResultsBean> myList; 
ArrayList<MapData.ResultsBean> allItems; 

Функция кнопки нажмите

menuOption1.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       myList = new ArrayList<MapData.ResultsBean>(); 
       allItems = new ArrayList<MapData.ResultsBean>(); 

       allItems.addAll(selectAllFrom("restaurant", myList)); 
       allItems.addAll(selectAllFrom("cafe", myList)); 
       allItems.addAll(selectAllFrom("bar", myList)); 

       Log.v("Size", "Places List size : " + allItems.size() + ""); 
      } 
     }); 

функция SelectAllFrom

private ArrayList<MapData.ResultsBean> selectAllFrom(final String type, final ArrayList<MapData.ResultsBean> list) { 

     // Creating an object of our api interface 
     ApiService myApi = RetroClient.getApiService(); 

     // Calling JSON 
     Call<MapData> call = myApi.getNearbyPlaces(type, mLastLocation.getLatitude() + "," + mLastLocation.getLongitude(), PROXIMITY_RADIUS); 

     call.enqueue(new Callback<MapData>() { 
      @Override 
      public void onResponse(Call<MapData> call, Response<MapData> response) { 

       Log.v("Response Code", "Response Code is : " + response.code()); 

       if (response.isSuccessful()){ 

        try { 
         // This loop will go through all the results 
         for (int i = 0; i < response.body().getResults().size(); i++) { 
          addToList(list, response.body().getResults().get(i)); 
         } 

         Log.v(type, "List Size : " + list.size() + ""); 

        } catch (Exception e) { 
         Log.d("onResponse", "There is an error"); 
         e.printStackTrace(); 
        } 

       } else { 
        Toast.makeText(getApplicationContext(), "Something work wrong", Toast.LENGTH_LONG).show(); 
       } 

      } 

      @Override 
      public void onFailure(Call<MapData> call, Throwable t) { 

       Toast.makeText(getApplicationContext(), "On Failure", Toast.LENGTH_LONG).show(); 
      } 
     }); 


     return list; 

    } 

и наконец, вот моя addToList функция

void addToList(ArrayList<MapData.ResultsBean> myList, MapData.ResultsBean item){ 
    if(!myList.contains(item)) 
     myList.add(item); 
} 

Это мой LogCat, размер allItem всегда возвращает 0

V/Size: Places List size : 0 
V/restaurant: List Size : 20 
V/bar: List Size : 21 
V/cafe: List Size : 41 
+0

Вы создаете два новых пустых списка в 'menuOption1.setOnClickListener', когда используете новый, а затем печатаете размер мест. – TDG

ответ

0

обратного вызова в call.enqueue(...) будет выполняться асинхронно. Это означает, что он может быть вызван в произвольное время в будущем.

Это означает, что ваш код делает это:

  • Вызов selectAllFrom
  • Вызов call.enqueue(...)
  • Возврат list, который до сих пор пусто на данный момент
  • Добавить пустой список allItems
  • [В какой-то более поздний момент] Вызовы addToList в обратном вызове

Это просто случай использования синхронного использования асинхронного ресурса. Это фактически условие гонки, так как асинхронный обратный вызов может быть вызван, когда selectAllFrom для другого значения вызывается, поскольку он использует общий myList, что приводит к неправильному ответу.

При использовании асинхронных ресурсов (например, при повторных настройках) вам нужно либо ждать значения (call.execute()), либо иметь дело с тем, что он замораживает пользовательский интерфейс или полностью фиксирует асинхронные способы выполнения действий.

EDIT: Также имейте в виду, что Android имеет строгие требования в отношении потоков и управления пользовательским интерфейсом. Toast.makeText() в обратном вызове, вероятно, вызовет исключения, так как обратный вызов не будет выполнен в потоке пользовательского интерфейса.

+0

Я вижу, так что я должен подождать, пока не закончится реакция на доработку, а затем перечислите список, я прав? – ysfcyln

+0

До тех пор, пока модификация не вернет список, он будет пустым. Как вы относитесь к асинхронному поведению, так это ваше решение в качестве разработчика – Kiskae

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