3

我有一个显示位图的简单网格视图。由于垃圾收集,视图非常糟糕。我有在列表视图中进行垃圾收集的经验,并且有一个相当重的运行顺利。但是我无法理解这里发生了什么。当我抛出视图时,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: (17979):WAIT_FOR_CONCURRENT_GC 阻塞 106 毫秒 12-20 13:22:46.187:D/dalvikvm(17979):WAIT_FOR_CONCURRENT_GC 阻塞 106 毫秒 12-20 13:22:46.187:D/dalvikvm(17979):WAIT_FOR_CONCURRENT_20 阻塞 13:77 22:46.187: D/dalvikvm(17979): WAIT_FOR_CONCURRENT_GC 阻塞 107 毫秒 12-20 13:22:46.191: D/dalvikvm(17979): WAIT_FOR_CONCURRENT_GC 阻塞 108 毫秒 12-20 13:22:46.191: D/dalvikITFOR_CURRENT9_GC_WAITFOR_CONCURRENT9:99阻塞 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 /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_CONCURRENT191_GC 阻塞 3:22:46。 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): WAIT110_CURRENT-_GC 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 阻塞了 114 毫秒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): WAIT110_CURRENT-_GC 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 阻塞了 114 毫秒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): WAIT110_CURRENT-_GC 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 阻塞了 114 毫秒WAIT_FOR_CONCURRENT_GC 阻塞了 114 毫秒WAIT_FOR_CONCURRENT_GC 阻塞了 114 毫秒

我正在使用的适配器是这样的......

公共类 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
  • 如果不再需要任务,则取消它,以希望不创建不必要的位图

到底是怎么回事?

4

1 回答 1

0

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

于 2012-12-20T14:23:12.157 回答