2016-12-10 60 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

當您使用new時,您在'menuOption1.setOnClickListener'處創建兩個新的空列表,然後打印場所的大小。 – TDG

回答

0

call.enqueue(...)回調將異步執行。這意味着它可以在未來的任意時間被調用。

這意味着你的代碼做的是:

  • 呼叫selectAllFrom
  • 電話call.enqueue(...)
  • 返回list,這仍然是空的,在這一點上
  • 空列表添加到allItems
  • [在稍後的時間點]在回撥中撥打addToList

這只是試圖同步使用異步資源的情況。這實際上是一種競爭條件,因爲當調用另一個值selectAllFrom時,可能會調用異步回調,因爲它使用共享myList,導致錯誤答案。

當使用異步資源(如Retrofit的調用)時,您需要等待一個值(call.execute())並處理凍結UI或完全提交異步執行方式的事實。

編輯:另請注意,Android對線程和操作UI有嚴格的要求。 Toast.makeText()在回調中可能會導致異常,因爲回調沒有在UI線程上執行。

+0

我明白了,所以我必須等到改造響應完成後再打電話清單,對嗎? – ysfcyln

+0

在改造返回之前,該列表將爲空。您如何處理異步行爲是您作爲開發人員的決定 – Kiskae