2016-05-09 51 views
0

我正在使用一個單例從Web服務中獲取數據並將結果數據對象存儲在ArrayList中。它看起來像這樣:ArrayList長度在單例中得到0

public class DataHelper { 

private static DataHelper instance = null; 

private List<CustomClass> data = null; 

protected DataHelper() { 
    data = new ArrayList<>(); 
} 

public synchronized static DataHelper getInstance() { 
    if(instance == null) { 
     instance = new DataHelper(); 
    } 
    return instance; 
} 

public void fetchData(){ 

    BackendlessDataQuery query = new BackendlessDataQuery(); 
    QueryOptions options = new QueryOptions(); 
    options.setSortBy(Arrays.asList("street")); 
    query.setQueryOptions(options); 

    CustomClass.findAsync(query, new AsyncCallback<BackendlessCollection<CustomClass>>() { 
     @Override 
     public void handleResponse(BackendlessCollection<CustomClass> response) { 

      int size = response.getCurrentPage().size(); 

      if (size > 0) { 
       addData(response.getData()); 
       response.nextPage(this); 
      } else { 
       EventBus.getDefault().post(new FetchedDataEvent(data)); 
      } 

     } 

     @Override 
     public void handleFault(BackendlessFault fault) { 
      EventBus.getDefault().post(new BackendlessFaultEvent(fault)); 
     } 
    }); 

} 

public List<CustomClass> getData(){ 
    return this.data; 
} 

public void setData(List<CustomClass> data){ 
    this.data = data; 
} 

public void addData(List<Poster> data){ 
    this.data.addAll(data); 
} 

public List<CustomClass> getData(FilterEnum filter){ 

    if(filter == FilterEnum.NOFILTER){ 
     return getData(); 
    }else{ 
     // Filtering and returning filtered data 
    } 

    return getData(); 
} 
} 

數據被正確提取並且列表實際上包含它之後的數據。而且,只按預期創建一個實例。但是,每當我稍後調用getData時,this.data的長度就是0.因此,我也嘗試使用持有DataHelper對象的Application的子類,導致相同的問題。

  1. 有沒有一種很好的調試方法?在Android Studio中是否有像全局手錶一樣的東西?
  2. 我的方法有什麼問題嗎?有更好的方法嗎?我主要是一個iOS開發人員,所以Android對我來說很新。我在不同的視圖中顯示ArrayList中的數據,因此只要應用程序運行,我就希望它在ArrayList中存在。

謝謝!

編輯:在列表視圖中的片段實施例使用(僅相關部分):

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    filter = FilterEnum.NOFILTER; 
    data = DataHelper.getInstance().getData(filter); 
} 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
customClassListAdapter = new customClassListAdapter(getActivity(), data);} 

EDIT2:增加代碼,我取從Backendless數據,在第一EDIT

改變DataHelper的參照數據的參照

EDIT3:我用一個本地EventBus通知有關新數據的列表視圖。這看起來像這樣和工程(初步數據被填充,但如應用過濾器後,我的getData得到的ArrayList是空的):

@Subscribe 
public void onMessageEvent(FetchedDataEvent event) { 
    customClassListAdapter.notifyDataSetChanged(); 
} 
+0

你可以嘗試在setter上添加一個斷點來捕獲它。同樣,你可以在單例初始化後的任何時候輸入以下內容:'DataHelper.getInstance()。getData()' –

+0

你如何使用這個類?如果您不止一次調用setData,它將覆蓋先前設置的數據。它也使構造函數中的「新的ArrayList <>()」成爲廢棄部分。這不一定是問題的原因,但可以取決於您如何使用課程。 – diidu

+0

嘗試使構造函數私人並檢查 –

回答

0

好吧,我終於找到了問題。這根本不是關於對象或內存管理。由於我將getData的引用提供給ArrayAdapter,因此無論何時在ArrayAdapter上調用clear(我在更改過濾器時執行該操作),都會清空引用。我基本上必須創建ArrayAdapter的結果副本:

data = new ArrayList<>(DataHelper.getInstance().getData(filter)); 

我沒有意識到這是一個參考的事實。因此,數據總是保留在幫手中。我只這樣做是因爲:

customClassListAdapter.notifyDataSetChanged(); 

在這裏沒有熱幫助,它不會再次使用新過濾器調用getData。

感謝大家的貢獻,你們肯定幫我調試過。

0

嘗試,而不是保持引用您的DataHelper例如,保持參考您檢索到的項目列表。 F.E.當你第一次獲取列表(並且可以像你說的那樣)時,將它分配給一個類成員。或者通過它來創建自己的數組列表以備將來使用。

+0

我在問題中添加了我對類的用法。所以你的意思不是在我的Fragment中有一個DataHelper的實例,我應該有一個方法getData的引用,像這樣:ArrayList list = DataHelper.getInstance()。getData(filter)? – mapf

+0

是的。並繼續參考。如果該數組列表實際上包含您的所有數據,並且除非從互聯網獲取新數據,否則此數據是固定的,它將始終包含您的數據。那麼,我的意思是說,直到無效或重新制定,當然。 – daxgirl

+0

爲了澄清,當你第一次從你的助手類中獲取列表時,將其分配給類成員。然後將其存儲在您的片段中,該片段保留設備旋轉f.e.上的實例。如果savedInstanceState不爲空(配置更改後),則獲取它。 – daxgirl

0

getData在填充數據之前很可能會被調用。

一個簡單的調試方法是添加(導入android.util.LogLog.i("MyApp.MyClass.MyMethod", "I am here now");條目到fetchData,addData和getData中的戰略位置,然後從adb logcat顯示的日誌中確保在調用getData之前填充數據。

+0

感謝您的評論。我想當我調用notifyDataSetHasChanged它重新獲取數據。由於元素的初始顯示有效,這不應該成爲問題。只有當例如更改過濾器並再次使用過濾器調用getData,ArrayList爲空。 – mapf

+0

而且你不會在任何地方調用setData? if語句的過濾分支可能有問題嗎? – diidu

+0

什麼是EventBus.getDefault()。post(new FetchedDataEvent(data));對數據做些什麼?它可以重置它嗎? setData肯定會,如果它被調用。 – diidu