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?
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);
}
}