I’m trying to implement a list/detail workflow where a tap on a list item causes the detail section to load data related to the newly selected row. I’m trying to use an AsyncTaskLoader to accomplish this. I’m running into a problem where if I tap three list items quickly enough in a row, only two of the loads actually occur and the third gets lost.
I’ve written a sample activity that demonstrates this behavior. When tapping the button three times, the loadInBackground() method is only getting called twice. Am I missing a call somewhere?
public final class LoaderActivity extends Activity implements LoaderManager.LoaderCallbacks<Integer> {
private Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loader);
button = (Button) findViewById(R.id.load_button);
getLoaderManager().initLoader(0, null, this);
}
public void onButtonClick(View source) {
Loader<Integer> loader = getLoaderManager().getLoader(0);
if (loader != null) {
loader.forceLoad();
}
}
@Override
public Loader<Integer> onCreateLoader(int id, Bundle args) {
return new IntLoader(this);
}
@Override
public void onLoadFinished(Loader<Integer> listLoader, Integer data) {
button.setText(String.valueOf(data));
}
@Override
public void onLoaderReset(Loader<Integer> listLoader) {
}
private static final class IntLoader extends AsyncTaskLoader<Integer> {
private static final AtomicInteger counter = new AtomicInteger(0);
IntLoader(Context context) {
super(context);
}
@Override
public Integer loadInBackground() {
int result = counter.getAndIncrement();
// Simulate a potentially expensive web call
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
return result;
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
protected void onReset() {
onStopLoading();
}
@Override
public void deliverResult(Integer data) {
if (isStarted()) {
super.deliverResult(data);
}
}
}
}
Calling
restartLoader(0, null, this)instead ofgetLoader(0)in theonButtonClick()method seems to have solved this problem. As I’m learning more aboutLoaders it sounds like the more appropriate method to call since I’m wanting to discard any old results at that point.