2012-08-02 91 views
2

我有一個活動,它實現了所有這些代碼所在的片段。通過一個例子可以很好地解釋這個問題,因爲代碼是保密的。這個例子反映了正在嘗試做什麼和通過測試我觀察到了什麼AsyncTaskLoader如何緩存數據?

例如)我有一個rss閱讀器片段,它從兩個獨特的Loader(Loader 1,Loader2)中獲取兩個唯一對象(A,B) )

Object A: 

int[] fullArticleIdList; 
List<ArticlePreview> partialArcticlePreviewList; 

Object B: 

List<ArticlePreview> partialArcticlePreviewList; 

在創建我呼籲裝載機1「initloader」的獲取對象A.通過可用的文章滾動後它擊中partialArcticlePreviewList從物體返回的底部和使用「restartloader裝載機2取更多文章它讀取對象B並允許用戶閱讀它們並繼續爲所有文章執行此操作。

這工作正常,直到用戶旋轉設備,因此調用onCreate。現在,在Loader 1上調用initloader時,它在連接到loader 1後立即跳轉到onLoadFinished並返回Loader 1.雖然articleIds正確返回,但返回的partialArcticlePreviewList是來自Loader 2的獲取對象B的那個。

加載器管理器是否只將對象的一個​​實例保存在緩存中並在多個加載器之間共享?看起來從廣泛的測試(5個小時試圖找到問題並查看Eclipse調試器中的加載器ID /緩存/地址),它使用它在Loader 2的partialArcticlePreviewList中收到的數據覆蓋了Loader 1的partialArcticlePreviewList。雖然這種情況對於單個Loader來說是理想的,但我會認爲每個Loaders的緩存都是獨立的。顯然裝載者的優點之一是通過屏幕旋轉和數據緩存的易用性和持久性,但它似乎並不像隱含的那樣工作。我們通過保留片段的實例並在onCreateView和onDestroyView中編寫適當的代碼來避免內存泄漏,但這是一個很好的解決方案,從而繞過了這個問題?

編輯:忘了補充,我們正在使用兼容性庫v4。另外,查看加載器的android源代碼似乎沒有揭示出爲什麼加載器爲其「mId」返回錯誤數據的情況。

回答

3

用於規避此問題的最終解決方案僅僅是自己管理數據而不依賴裝載器。

當他們只爲屏幕加載一件東西時,加載程序很好地保留數據,但對於分頁,他們創建了所有這些麻煩,而且它們的操作方式仍然沒有很好理解;結論是,它們沒有按預期運行,或者我們的實現有問題,只有在更高級的用例中才顯現出來。

要自己管理數據,我們正在使用捆綁/保留碎片的組合,同時小心地在onDestroyView中正確地清理所有內容。我們還會使加載程序檢查我們的數據集在旋轉後執行回調時是否已經有數據,因此我們不會將分頁數據兩次添加到數據集中。另一種選擇是使用單例對象。

希望這可以幫助別人在未來。

+0

我一直試圖解決這個問題一個星期了,你有沒有我能看到的任何示例代碼?謝謝!。 – 2014-07-29 21:50:02

+0

我沒有代碼,但你可以嘗試https://stackoverflow.com/questions/7181526/example-of-implementing-parcelable。基本上只是使用asynctaskloader來獲取數據並將其存儲在一個最初的包中,然後在隨後的回調中忽略asynctaskloader。然後可以將parcelable用於正常的生命週期條件。 – 2014-07-29 22:51:43