Android-异步加载图片

来源:互联网 发布:java大数据是什么 编辑:程序博客网 时间:2024/06/06 02:51

转载请标明出处:http://blog.csdn.net/goldenfish1919/article/details/38559205

原文:http://developer.android.com/training/displaying-bitmaps/process-bitmap.html

ListView中加载图片的时候,为了防止图片错位,通常会给图片设置一个tag,今天听同事说google官网上有一种很牛逼的实现,然后看了下,google给出的代码实现的非常巧妙,而且还不用设置额外的tag,它是把ImageView和AsyncTask绑定到一块,如果imageView重用就把task取消。

public void loadBitmap(int resId, ImageView imageView, Bitmap mPlaceHolderBitmap) {// 取消任务,重新绑定if (cancelPotentialWork(resId, imageView)) {// 任务绑定一个imageViewfinal BitmapWorkerTask task = new BitmapWorkerTask(imageView);// imageView绑定一个任务,imageView可能会重用,但是task不会final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);imageView.setImageDrawable(asyncDrawable);// 执行任务task.execute(resId);}}public static boolean cancelPotentialWork(int latestData, ImageView imageView) {final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);if (bitmapWorkerTask != null) {final int bitmapData = bitmapWorkerTask.data;// If bitmapData is not yet set or it differs from the new dataif (bitmapData == 0 || bitmapData != latestData) {// Cancel previous taskbitmapWorkerTask.cancel(true);} else {// The same work is already in progressreturn false;}}// No task associated with the ImageView, or an existing task was// cancelledreturn true;}class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {private final WeakReference<ImageView> imageViewReference;private int data = 0;public BitmapWorkerTask(ImageView imageView) {// Use a WeakReference to ensure the ImageView can be garbage// collectedimageViewReference = new WeakReference<ImageView>(imageView);}// Decode image in background.@Overrideprotected Bitmap doInBackground(Integer... params) {data = params[0];return decodeSampledBitmapFromResource(getResources(), data, 100, 100);}@Overrideprotected void onPostExecute(Bitmap bitmap) {if (isCancelled()) {bitmap = null;}if (imageViewReference != null && bitmap != null) {final ImageView imageView = imageViewReference.get();final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);if (this == bitmapWorkerTask && imageView != null) {imageView.setImageBitmap(bitmap);}}}}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();}}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;}public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId, int reqWidth, int reqHeight) {// First decode with inJustDecodeBounds=true to check dimensionsfinal BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);try{Thread.sleep(new Random().nextInt(1000));}catch(Exception e){}// Calculate inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);// Decode bitmap with inSampleSize setoptions.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);}public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {// Raw height and width of imagefinal int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {final int halfHeight = height / 2;final int halfWidth = width / 2;// Calculate the largest inSampleSize value that is a power of 2 and// keeps both// height and width larger than the requested height and width.while ((halfHeight / inSampleSize) > reqHeight&& (halfWidth / inSampleSize) > reqWidth) {inSampleSize *= 2;}}return inSampleSize;}
类似的实现还有:

http://blog.csdn.net/goldenfish1919/article/details/25374731 这个能防止多次下载

http://blog.csdn.net/lmj623565791/article/details/38476887 这个非常有意思,用子线程的Handler来实现,还可以实现先加载最后一页的图片。

0 0
原创粉丝点击