ビットマップを表示する単純なグリッドビューがあります。ガベージコレクションのため、ビューは非常にぎくしゃくしています。リストビューでのガベージコレクションの経験があり、かなり重いものがスムーズに実行されています。しかし、ここで何が起こっているのか理解できません。ビューをフリングすると、UIスレッドが非常にブロックされます。スタックトレースは次のようになります
12-20 13:22:46.187:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが106msをブロック12-20 13:22:46.187:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが106msをブロック12-20 13:22:46.187:D / dalvikvm (17979):WAIT_FOR_CONCURRENT_GCブロック106ms 12-20 13:22:46.187:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCブロック106ms 12-20 13:22:46.187:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCブロック107ms 12-20 13: 22:46.187:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが107msをブロック12-20 13:22:46.191:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが108msをブロック12-20 13:22:46.191:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCブロックされた108ms12-2013:22:46.191:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCブロックされた109ms 12-20 13:22:46.191:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCブロックされた108ms 12-20 13:22:46.191:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCブロック108ms12-2013:22:46.191:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCブロック109ms 12-20 13:22:46.191:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCブロック109ms 12-20 13:22:46.191: D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが111msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12- 20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが111msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12-20 13:22:46.195:D / dalvikvm(17979 ):WAIT_FOR_CONCURRENT_GCが114msをブロックしましたD / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが111msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12- 20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが111msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12-20 13:22:46.195:D / dalvikvm(17979 ):WAIT_FOR_CONCURRENT_GCが114msをブロックしましたD / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが111msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12- 20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが111msをブロック12-20 13:22:46.195:D / dalvikvm(17979):WAIT_FOR_CONCURRENT_GCが110msをブロック12-20 13:22:46.195:D / dalvikvm(17979 ):WAIT_FOR_CONCURRENT_GCが114msをブロックしましたWAIT_FOR_CONCURRENT_GCが114msをブロックしましたWAIT_FOR_CONCURRENT_GCが114msをブロックしました
私が使っているアダプターはこんな感じです。
パブリッククラスPhotoSelectorAdapterはBaseAdapterを拡張します{
private Context context;
private String[] paths;
private final Executor executor = Executors.newFixedThreadPool(20);
public PhotoSelectorAdapter(Context context, String[] paths) {
this.context = context;
this.paths = paths;
}
public int getCount() {
return paths.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
ImageGetter imageGetter;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
imageView.setImageBitmap(null);
imageGetter = (ImageGetter) imageView.getTag();
if (imageGetter != null) {
imageGetter.cancel(true);
}
}
imageGetter = new ImageGetter(context, paths[position], imageView);
executor.execute(imageGetter.future());
imageView.setTag(imageGetter);
return imageView;
}
class ImageGetter extends RoboAsyncTask<Bitmap> {
private WeakReference<ImageView> imageViewReference;
private String path;
BitmapFactory.Options options = new BitmapFactory.Options();
protected ImageGetter(Context context, String path, ImageView imageView) {
super(context);
this.path = path;
this.imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
public Bitmap call() throws Exception {
options.inSampleSize = 10;
return BitmapFactory.decodeFile(path, options);
}
@Override
protected void onSuccess(Bitmap bitmap) throws Exception {
super.onSuccess(bitmap);
if (future.isCancelled()) {
bitmap = null;
} else {
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
}
ガベージコレクションを回避するために私が取った手順は次のとおりです。
- ビットマップのサンプルサイズを10にする
- 不要なビットマップを作成しないことを期待して、タスクが不要になった場合にタスクをキャンセルする
何が起こっている?