【Google官方教程】第四课:在UI中显示Bitmap(4)

当然,问题还是这个方法在UI线程中处理图片。这种方式或许是和处理小而简单的图片(系统资源的加载和缓存),如果需要做任何的处理,UI就会被阻塞(甚至引起ANR(Application Not Responding))。

和前一节相同的处理方式,我们在异步线程中进行处理和缓存。然而,考虑到GridView回收子视图的方式,你需要谨慎处理并发问题。可以使用“在非UI线程中处理Bitmap”一课中提到的技巧。这里是更新的解决方案:

public class ImageGridFragment extends Fragment implements AdapterView.OnItemClickListener {
    ...

private class ImageAdapter extends BaseAdapter {
        ...

@Override
        public View getView(int position, View convertView, ViewGroup container) {
            ...
            loadBitmap(imageResIds[position], imageView)
            return imageView;
        }
    }

public void loadBitmap(int resId, ImageView imageView) {
        if (cancelPotentialWork(resId, imageView)) {
            final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
            final AsyncDrawable asyncDrawable =
                    new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
            imageView.setImageDrawable(asyncDrawable);
            task.execute(resId);
        }
    }

static class AsyncDrawable extends BitmapDrawable {
        private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

public AsyncDrawable(Resources res, Bitmap bitmap,
                BitmapWorkerTask bitmapWorkerTask) {
            super(res, bitmap);
            bitmapWorkerTaskReference =
                new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
        }

public BitmapWorkerTask getBitmapWorkerTask() {
            return bitmapWorkerTaskReference.get();
        }
    }

public static boolean cancelPotentialWork(int data, ImageView imageView) {
        final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

if (bitmapWorkerTask != null) {
            final int bitmapData = bitmapWorkerTask.data;
            if (bitmapData != data) {
                // Cancel previous task
                bitmapWorkerTask.cancel(true);
            } else {
                // The same work is already in progress
                return false;
            }
        }
        // No task associated with the ImageView, or an existing task was cancelled
        return true;
    }

private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
      if (imageView != null) {
          final Drawable drawable = imageView.getDrawable();
          if (drawable instanceof AsyncDrawable) {
              final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
              return asyncDrawable.getBitmapWorkerTask();
          }
        }
        return null;
    }

... // include updated BitmapWorkerTask class

注意:相同的代码也可以很好的适配ListView。

这里的实现方法允许灵活地处理和加载图片,并且不会影响UI的流畅性。在后台线程中,你可以从网络加载图片,调整大幅的数码相机照片的大小,并在处理任务结束的时候将图片显示在UI界面中。

要了解在本节课中讨论到的概念和完整代码,请参阅示例程序。

BitmapFun:

免费下载地址在

用户名与密码都是

具体下载目录在 /2012年资料/11月/13日/【Google官方教程】第四课:在UI中显示Bitmap

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/37457e6c286a4d4fe2a6168a97c6e32c.html