Android之Bitmap大图加载处理
来源:互联网 发布:南木梁知小说百度云盘 编辑:程序博客网 时间:2024/05/21 17:43
在Android中显示图片一般使用ImageView,通过setImageBitmap()、setImageResource()等方法指定要显示的方法,而这些方法最终都会调用到BitmapFactory.decode()方法来生成一个Bitmap进行显示。对于一般的小图片这样使用没有什么问题,因为垃圾回收器会及时将不用的图片进行回收,但连续加载大图片的时候就会发生典型的OOM问题,也就是内存溢出,这是因为在Android系统中虚拟机为每一个应用程序都分配了指定内存大小,如果使用超出了这个限制就会发生内存溢出导致程序崩溃。
因此要避免OOM的问题就需要对大图片的加载进行管理,主要通过缩放来减小图片的内存占用。
1、Bitmap的缩放
生成Bitmap都要通过BitmapFactory的decode()方法,使用此方法时可以传入一个解析参数BitmapFactory.Option来对控制解析过程,比如获得长宽、改变采样率、改变采样格式等。而对Bitmap的缩放就是通过改变采样率来实现的,具体操作如下:
1)计算实际采样率
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float) height / (float) reqHeight); } else { inSampleSize = Math.round((float) width / (float) reqWidth); } return inSampleSize; }
2)由得到的采样率对图片进行解析
public static Bitmap decodeSampledBitmapFromFile(String filename, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filename, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(filename, options); }
这样就可以对图片实现缩放的功能了,缩放的内存大小是实际的1/(samplesize^2)。但这里还有一个问题,就是实际解析图片的时候是从硬盘上读取的,当图片较大的时候这个解析时间是不确定的,如果直接在UI线程中执行,会观察到明显的停顿,再时间长一点就ANR了,所以需要将图片解析的过程放在异步操作了,可以单开一个线程,也可以使用系统提供的异步任务类AsyncTask,示例如下:
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { private final WeakReference<ImageView> imageViewReference; private String data = null; public BitmapWorkerTask(ImageView imageView) { // Use a WeakReference to ensure the ImageView can be garbage collected imageViewReference = new WeakReference<ImageView>(imageView); } // Decode image in background. @Override protected Bitmap doInBackground(String... params) { data = params[0]; return decodeSampledBitmapFromFile(data, 100, 100)); } // Once complete, see if ImageView is still around and set bitmap. @Override protected void onPostExecute(Bitmap bitmap) { if (imageViewReference != null && bitmap != null) { final ImageView imageView = imageViewReference.get(); if (imageView != null) { imageView.setImageBitmap(bitmap); } } }}
这里需要传入ImageView,当后台图片解析完成后就会将图片加载进行显示。
关于Bitmap图片的加载Google官网上有详细的教程讲解,除了解析还有缓存的解决方案
http://developer.android.com/intl/zh-CN/training/displaying-bitmaps/index.html
- Android之Bitmap大图加载处理
- Android开发Bitmap加载大图
- Android的Bitmap处理大图片解决方法
- Android Bitmap二次采样,大图处理
- android 加载大图片处理
- Android简单示例之处理加载大图片到内存
- Android异步加载全解析之大图处理
- AndroidのBitmap之大图片优化
- Android Bitmap大量使用不产生OOM之“加载大图片资源优化”
- Android Bitmap大量使用不产生OOM之“加载大图片资源优化”
- 如何加载大图片及bitmap相关处理
- 加载本地大图后Bitmap oom的处理
- Bitmap处理 之二高效处理大图片
- Bitmap 处理 之加载大的Bitmap
- Android中对加载大图的处理
- android加载大图片时oom问题处理
- Bitmap加载大图优化之位图重采样与Bitmap缓存Lru算法分析
- Android自助餐之大图片加载
- 老外最常说的二十个钻石级句子
- Asp.net web Api源码分析-Action的执行
- 有关L6236E,L6406E错误的总结
- Jquery queue源码分析
- 小游戏 (最少线段连线问题)
- Android之Bitmap大图加载处理
- 4.1 内存的分配与释放
- HDU 1232 & 1213并查集应用 练习
- 宁坐在切糕车上哭 也不坐在宝马车里笑
- 软件项目管理系统-项目管理-模块一览
- 放大效应
- VS2008提示无法打开包括文件:“afxcontrolbars.h”解决办法
- sql server 首字母大写
- 4.2 使用LIST_ENTRY4.3 使用自旋锁