0

我有一個加載程序。我希望它只能在底層數據模型更改時啓動。我認爲這是裝載機的要點。從Android文檔:加載程序重新啓動活動啓動混亂

裝載程序,特別是CursorLoader,預計在停止後保留其數據 。這允許應用程序跨活動或片段的onStop()和onStart()方法保留其數據 ,因此 當用戶返回到應用程序時,他們不必等待 數據重新加載。

太好了。但是,每當我的活動恢復時,我的加載器onStartLoading()都會被調用。調試到平臺代碼中,Activity.onStart()的實現最終將重新啓動所有加載器。具體的調用堆棧,

Activity.onStart() --> 
FragmentController..doLoaderStart() --> 
FragmentHostCallback.doLoaderStart() --> 
LoaderManagerImpl.doStart() --> 
LoadermanagerImpl.LoaderInfo.start() --> 
Loader.startLoader() --> 
<my loader>.onStartLoading() 

我的裝載機是昂貴的,所以我不希望它重新加載時,我的活動重新啓動,這似乎違背上述其中特別指出裝載機都應該保留的報價他們的數據跨越停止/啓動週期。

這是否有意義?

+0

只是一個提示。您應該真正考慮使用生命週期組件而不是加載器。這裏有一篇很好的文章解釋了Loaders,生命週期和狀態的更多信息:https:// medium。com/google-developers/viewmodels-persistence-onsaveinstancestate-restoring-ui-state-and-loaders -fc7cc4a6c090 – Peter

+0

你可以分享你調用'getLoaderManager.initLoader()'的地方嗎? – chessdork

+0

甚至有[關於從加載程序轉換爲體系結構組件的博客文章](https://medium.com/google-developers/lifecycle-aware-data-loading-with-android-architecture-components-f95484159de4) – ianhanniballake

回答

1

回答我自己。

這個問題基本上是對裝載機的誤解。當框架調用LoaderonStartLoading()時,它更像是一個生命週期方法。這是一個框架,告訴你的裝載機該活動已經開始。與我原先的想法相反,這並不意味着加載器必須重新加載它的數據。

加載器(像我的)的一個天真的實現只是重新加載它的所有數據在onStartLoading()。只有在底層數據發生變化時纔會加載更智能的實現。如果我們看一下CursorLoader.onStartLoading()

@Override 
protected void onStartLoading() { 
    if (mCursor != null) { 
     deliverResult(mCursor); 
    } 
    if (takeContentChanged() || mCursor == null) { 
     forceLoad(); 
    } 
} 

它首先將立即如果它有它的緩存的結果。然後它調用forceLoad()實際加載數據,但它只有在數據已更改時纔會執行此操作。

另一個細節是如何跟蹤內容何時發生變化。它歸結爲Loader的實施onContentChanged()

public void onContentChanged() { 
    if (mStarted) { 
     forceLoad(); 
    } else { 
     // This loader has been stopped, so we don't want to load 
     // new data right now... but keep track of it changing to 
     // refresh later if we start again. 
     mContentChanged = true; 
    } 
} 

這個方法說:作爲我們開始了內容已經改變,加載數據。否則,只要保持一個標誌,讓我們知道內容已經改變。它基本上延遲了數據的實際加載,直到加載程序啓動。

takeContentChanged()基本檢查mContentChanged實例字段:

public boolean takeContentChanged() { 
    boolean res = mContentChanged; 
    mContentChanged = false; 
    mProcessingChange |= res; 
    return res; 
} 

只要您的裝載機實現調用onContentChanged()當內容發生了變化,中Loader實施處理剩下的。