これは Android の質問というよりは Java の質問かもしれませんが、AsyncTask 内で作成されたビットマップを取得して別のクラス (アクティビティ) に保存するのに苦労しているので、使い終わったらリサイクルできます。
AsyncTask は doInBackground() で Bitmap を作成し、onPostExecute() で ImageView のビットマップとして設定します。ImageView はコンストラクターを介して渡されます。しかし、完了後、アクティビティでビットマップにアクセスできるようにしたいと考えています。アクティビティには ImageView の ArrayList と別のビットマップがありますが、AsyncTask が新しいビットマップを作成するため、アクティビティのビットマップの ArrayList でこの新しいオブジェクトを取得する簡単な方法が見つかりません。現在、リストへのインデックスとともにArrayListをAsyncTaskコンストラクターに渡すことで機能しており、doInBackgroundは配列内のそのエントリを新しく作成されたビットマップに設定するだけです。
おそらく、アクティビティにビットマップのArrayListがない場合など、このAsyncTaskをさまざまなことに使用できるようにしたいので、このソリューションは好きではありません。また、AsyncTask コンストラクターに Bitmap を単純に与えることはできません。Java は参照を値渡しし、それを新しい Bitmap オブジェクトに設定すると、呼び出し元がアクセスできなくなるからです。
これをよりエレガントにするにはどうすればよいですか?
関連するコードは次のとおりです。この質問に関係のない行は、わかりやすくするために省略されています。
public class LoadCachedImageTask extends AsyncTask<String, Void, Void> {
private Context context;
private ImageView image;
private ArrayList<Bitmap> bitmaps;
int index;
public LoadCachedImageTask(Context context, ImageView image, ArrayList<Bitmap> bitmaps, int index) {
this.context = context;
this.image = image;
this.bitmaps = bitmaps;
this.index = index;
}
protected Void doInBackground(String... urls) {
String url = urls[0];
Bitmap bitmap = null;
// Create the bitmap
File imageFile = new File(context.getCacheDir(), "test");
bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
// Set the bitmap to the bitmap list
bitmaps.set(index, bitmap);
return null;
}
protected void onPostExecute(Void arg) {
// Display the image
image.setImageBitmap(bitmaps.get(index));
}
protected void onCancelled() {
if (bitmaps.get(index) != null) {
bitmaps.get(index).recycle();
bitmaps.set(index, null);
}
}
}
そして、これを使用するサンプル アクティビティを次に示します。
public class SampleActivity extends Activity {
private ArrayList<ImageView> images;
private ArrayList<Bitmap> bitmaps;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
images = new ArrayList<ImageView>();
bitmaps = new ArrayList<Bitmap>();
int numImages = 15;
// Create the images and bitmaps
for (int i = 0; i < numImages; i++) {
images.add(new ImageView(this));
bitmaps.add(null);
}
// Load the bitmaps
for (int i = 0; i < numImages; i++) {
new LoadCachedImageTask(this, images.get(i), bitmaps, i).execute("http://random.image.url");
}
}
}
上記のコードをテストしていないので、うまくいかないかもしれませんが、要点はわかると思います。