AsyncTaskLoader does not cache data offline

46 views Asked by At

I have created an AsyncTaskLoader for loading JSON data from an API. However, I noticed that if I rotate the screen of my device, it tries to load the data from the API again.

As a result, if I turn off my Internet connection and rotate the screen, the loader fails to return data since the HTTP request fails.

// NewsLoader.java
public class NewsLoader extends AsyncTaskLoader<String> {
    private String url;

    public NewsLoader(@NonNull Context context, String url) {
        super(context);
        this.url = url.trim();
    }

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

    @Override
    public String loadInBackground() {
        if (url == null || url.isEmpty()) return null;
        return NetworkUtils.fetchNews(url);
    }
}

Then,

// NewsActivity.java

// Initialising the loader
LoaderManager.getInstance(this).initLoader(LOADER_ID, args, this);

// onCreateLoader method
public Loader<String> onCreateLoader(int id, @Nullable Bundle args) {
    // Process args and get url
    return new NewsLoader(this, url);
}

As far as I know, this isn't normal behaviour for a loader. Any idea what is wrong?

1

There are 1 answers

0
Victor Durojaiye On BEST ANSWER

I eventually figured out what the problem was. The data has to be cached manually, intercepting the loaded data within deliverResult() and saving it in an instance variable for later use.

Here is the updated code.

// NewsLoader.java
public class NewsLoader extends AsyncTaskLoader<String> {
    private String url;
    private String cachedData = null;

    public NewsLoader(@NonNull Context context, String url) {
        super(context);
        this.url = url.trim();
    }

    @Override
    protected void onStartLoading() {
        if (cachedData != null) deliverResult(cachedData);
        else forceLoad();
    }

    @Override
    public String loadInBackground() {
        if (url == null || url.isEmpty()) return null;
        return NetworkUtils.fetchNews(url);
    }

    @Override
    public void deliverResult(String data) {
        cachedData = data;
        super.deliverResult(data);
    }
}