帶快取的 AsyncTaskLoader

快取載入的結果是一種很好的做法,以避免多次載入相同的資料。
要使快取無效,應呼叫 onContentChanged()。如果已經啟動了 loader,則會呼叫 forceLoad(),否則(如果處於停止狀態的載入器)載入器將能夠通過 takeContentChanged() 檢查瞭解內容更改。

備註:必須從程序的主執行緒呼叫 onContentChanged()

Javadocs 說關於 takeContentChanged()

獲取當前標誌,指示載入程式的內容在停止時是否已更改。如果有,則返回 true 並清除標誌。

public abstract class BaseLoader<T> extends AsyncTaskLoader<T> {

    // Cached result saved here
    private final AtomicReference<T> cache = new AtomicReference<>();

    public BaseLoader(@NonNull final Context context) {
        super(context);
    }

    @Override
    public final void deliverResult(final T data) {
        if (!isReset()) {
            // Save loaded result
            cache.set(data);
            if (isStarted()) {
                super.deliverResult(data);
            }
        }
    }

    @Override
    protected final void onStartLoading() {            
        // Register observers
        registerObserver();

        final T cached = cache.get();    
        // Start new loading if content changed in background
        // or if we never loaded any data
        if (takeContentChanged() || cached == null) {
            forceLoad();
        } else {
            deliverResult(cached);
        }
    }

    @Override
    public final void onStopLoading() {
        cancelLoad();
    }

    @Override
    protected final void onReset() {
        super.onReset();
        onStopLoading();
        // Clear cache and remove observers
        cache.set(null);
        unregisterObserver();
    }

    /* virtual */
    protected void registerObserver() {
        // Register observers here, call onContentChanged() to invalidate cache
    }

    /* virtual */
    protected void unregisterObserver() {
        // Remove observers
    }
}