带缓存的 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
    }
}