GridView垃圾收集

时间:2012-12-20 12:27:47

标签: android

我有一个显示位图的简单gridview。由于垃圾收集,视图非常粗糙。我已经在listviews中体验过垃圾收集,并且运行顺畅,重量很重。但是我无法理解这里发生了什么。当我浏览视图时,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阻止了108ms 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阻止了108ms   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   封锁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阻止了110毫秒12-20 13:22:46.195:   D / dalvikvm(17979):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的样本大小
  • 如果不再需要取消任务,希望不创建不必要的位图

发生了什么事?

1 个答案:

答案 0 :(得分:0)

你的影像有多大?即使在后台完成,也可能过多地解码它们太多。如果您创建了内存中的缩略图缓存,则可能会减少垃圾。您还可以将缩略图保存到磁盘,并在内存缓存已满时让缓存从中加载缓存。