Android 高效加载图片
来源:互联网 发布:淘宝助理五笔怎么打? 编辑:程序博客网 时间:2024/04/29 19:00
1.加载合适大小的图片
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); // inJustDecodeBounds set true,只获取图片信息 options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // 获取缩小倍数 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // inJustDecodeBounds set false options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options);}//测量缩小倍数public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // 获取图片宽高 final 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; //将inSampleSize设置成2的指数倍 while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize;}
2.异步加载图片
简单的异步加载图片
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { private final WeakReference<ImageView> imageViewReference; private int data = 0; public BitmapWorkerTask(ImageView imageView) { // 使用WeakReference存储imageView,因为imageView可能会被GC回收,如果被GC回收,那么就说明就不用加载图片 imageViewReference = new WeakReference<ImageView>(imageView); } // 异步加载图片 @Override protected Bitmap doInBackground(Integer... params) { data = params[0]; return decodeSampledBitmapFromResource(getResources(), data, 100, 100)); } // 加载完成,确定imageView是否还存在 @Override protected void onPostExecute(Bitmap bitmap) { if (imageViewReference != null && bitmap != null) { final ImageView imageView = imageViewReference.get(); if (imageView != null) { imageView.setImageBitmap(bitmap); } } }}
使用
public void loadBitmap(int resId, ImageView imageView) { BitmapWorkerTask task = new BitmapWorkerTask(imageView); task.execute(resId);}
如果在ListView,和GridView中使用,往往会因为用户的滑动,会产生大量的异步线程,还可能导致图片的重复加载,或者是加载了图片却并不需要显示(该条目已经不需要显示)。那么就要进行同步处理。
首先,避免不必要的task运行,可以采用之前用WeakReference存储ImageView的方法,将task和目标图片关联起来。在这里,可以采用创建BitmapDrawable 的子类来进行管理。
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(); }}
在执行task之前,将图片和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); }}
判断task是否必要执行
public static boolean cancelPotentialWork(int data, 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 data if (bitmapData == 0 || 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;}//判断task是否已经创建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;}
最后,修改之前的代码,判断ImageView和task,确定图片是否应该显示
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { ... @Override protected 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); } } }}
1 0
- android高效加载图片
- Android 高效加载图片
- Android高效加载大量图片
- android图片:高效加载大图
- Android 打造高效的图片加载框架
- Android-高效加载图片经验分享
- Android 图片如何高效加载与缓存
- Android设置采样率高效加载图片
- 高效异步加载图片
- 图片高效加载
- 高效加载图片
- Bitmap高效加载图片
- 高效加载图片
- Bitmap 高效加载图片
- 高效加载图片
- Android高效加载图片,有效避免程序OOM
- Android高效加载图片,有效避免程序OOM
- Android高效加载图片,有效避免程序OOM
- 可视化篇:R可视化--map图
- vertical-align 和 line-height 的关系
- Apache kafka 工作原理介绍(作者原创文章已发表在IBM开发者论坛)
- 霍夫曼树及霍夫曼编码的C语言实现
- solr配置中文分词遇到的问题
- Android 高效加载图片
- BroadcastReceiver
- tomcat的几个常见问题
- TCP数据传输(六):上传图片并给出反馈
- 61.JAVA编程思想——共享有限资源
- 用oracle语句计算百分比
- ubuntu kylin14.04 上 android 5.1.1源码下载,编译
- 62.JAVA编程思想——线程堵塞
- html5绘制变换图形-旋转图形