リスト アクティビティを使用して、インターネットから取得したアイテムのリストを表示する Android アプリを入手しました。最初に AsyncTask を使用してリストをロードし、その非同期タスクが完了すると、別の非同期タスクを呼び出して、リスト アイテムに付随するサムネイル画像のロードを開始します。私が抱えている問題は、ユーザーがいつでも押すことができる更新ボタンにアクセスでき、それを押すと、アイテムのリスト全体が削除され、読み込みが最初からやり直すことです。これが発生した場合、サムネイルをロードする Async タスクがまだ実行されている可能性があり、存在しないリスト項目にサムネイルを追加しようとする可能性があります。ブール値を使用してリストを同期しようとしましたが、調査した結果、機能しないことがわかりました。また、静的アトミック ブール値を使用して、サムネイル ローダーをキャンセルするために更新がヒットしたかどうかを確認しようとしました。
public class LoadItems extends AsyncTask<Void, Void, Boolean> {
private Activity activity;
private static boolean loading = false;
public static final AtomicBoolean refreshing = new AtomicBoolean(false);
private static final String TAG = "LoadItems";
private int start;
private List<ListItem> items;
public LoadItems(Activity activity) {
this.activity = activity;
}
@Override
protected void onPreExecute() {
loading = true;
start = ItemViewer.itemList.size();
}
@Override
protected Boolean doInBackground(Void... arg0) {
items = WebFunctions.getMoreItems(activity);
return (items != null);
}
protected void onPostExecute(Boolean success) {
if (success) {
for (ListItem item: items) {
ItemViewer.itemList.add(item);
Log.d(TAG, "added item " + item.getTitle());
}
LoadThumbnails thumbnailLoader = new LoadThumbnails();
thumbnailLoader.execute(start, ItemViewer.itemList.size());
}
loading = false;
}
public void protectedExecute() {
if (!loading)
execute();
}
public void refresh() {
if (!refreshing.getAndSet(true)) {
WebFunctions.reset();
ItemViewer.itemList.removeAllItems();
execute();
}
}
}
public class LoadThumbnails extends AsyncTask<Integer, Void, Drawable> {
private int position;
private int end;
@Override
protected Drawable doInBackground(Integer... params) {
position = params[0];
end = params[1];
Drawable thumbnail = null;
synchronized(ItemViewer.itemList) {
if (LoadItems.refreshing.get())
cancel(true);
String url = ItemViewer.itemList.get(position).getThumbnailUrl();
if (!url.isEmpty())
thumbnail = WebFunctions.loadDrawableFromUrl(ItemViewer.activity, url);
}
return thumbnail;
}
protected void onPostExecute(Drawable d) {
synchronized (ItemViewer.itemList) {
if (LoadItems.refreshing.get())
cancel(true);
if (d != null)
ItemViewer.itemList.setThumbnail(position, d);
position++;
if (position < end) {
LoadThumbnails lt = new LoadThumbnails();
lt.execute(position, end);
}
}
}
}