Refreshing a Loader without discarding previous data

41 Views Asked by At

I'm writing an Android application that uses an AsyncTaskLoader handled by a LoaderManager to acquire some data. The data can be modified upstream when the app is open, but as loading the data is time-consuming I check if it has been modified first.

I cache the result and the last-modified field, and my loadInBackground() method first checks if the upstream data has been modified before loading the actual data. Checking the upstream last-modified field is also time-consuming, and therefore must be done inside the AsyncTaskLoader, not on the UI thread.

public class DataActivity extends Activity implements LoaderManager.LoaderCallbacks<LoadedData> {

    // ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
        getLoaderManager().initLoader(0, null, this);
    }

    private void reloadData() { // called from various locations
        getLoaderManager().restartLoader(0, null, this);
    }

    @Override
    public Loader<LoadedData> onCreateLoader(int i, Bundle bundle) {
        return new DataLoader(this);
    }

    @Override
    public void onLoadFinished(Loader<LoadedData> loader, LoadedData result) {
        setActivityLoadingState(false);
        updateShownData(result);
    }

    @Override
    public void onLoaderReset(Loader<LoadedData> loader) {}

    private static class DataLoader extends AsyncTaskLoader<LoadedData> {
        private LoadedData lastData;
        private int lastModified = -1;

        GameListLoader(DataActivity activity) {
            super(activity);
        }

        @Override
        public LoadedData loadInBackground() {
            int currentModified = getUpstreamLastModified();
            if (currentModified == lastModified)
                return lastData;
            LoadedData currentData = getUpstreamData();
            lastData = currentData;
            lastModified = currentModified;
            return currentData;
        }

        @Override
        protected void onStartLoading() {
            forceLoad();
            setActivityLoadingState(true);
        }
    }
}

Now, I noticed that the LoaderManager.restartLoader method creates a new Loader every time, which discards my cache entirely, and loads the data every time.

Is there a way to ask the AsyncTaskLoader to refresh (i.e. call its startLoading, as I have onStartLoading calling forceLoad) from the LoaderManager? Or should I not be using LoaderManager or AsyncTaskLoader at all?

0

There are 0 best solutions below