解决读取bitmap内存溢出问题
来源:互联网 发布:mysql 修改列字符集 编辑:程序博客网 时间:2024/06/05 03:48
官方文档解决办法:http://developer.android.com/training/displaying-bitmaps/index.html
一、有效的加载大图(Loading Large Bitmaps Efficiently)
1.读取图片的密度和类型(Read Bitmap Dimensions and Type)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //设置为true调用BitmapFactory的decode方法不会分配内存,返回一个空的bitmap
BitmapFactory.decodeResource(getResources(), R.id.myimage, options); //返回为null ,不分配内存
int imageHeight = options.outHeight; //图片的高度
int imageWidth = options.outWidth; //图片的宽度
String imageType = options.outMimeType; //图片的类型
根据图片的高度和宽度可以计算出图片的密度,是否大于系统要求的内存,防止内存溢出,然后设置options.inJustDecodeBounds = false;
否则用BitmapFactory生成的Bitmap返回值为null
2.加载缩小的图片到内存(Load a Scaled Down Version into Memory)
options.inSampleSize = 3; 通过BitmapFactory得到的Bitmap宽度是原图的1/3,高度也是原图的1/3。
二、脱离UI线程(Processing Bitmaps Off the UI Thread)
使用AsyncTask,在主线程中加载大量图片会导致,看起来机子很卡
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 collected imageViewReference = new WeakReference<ImageView>(imageView); //使用弱引用 } // Decode image in background. @Override protected Bitmap doInBackground(Integer... params) { data = params[0]; return decodeSampledBitmapFromResource(getResources(), 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); } } }}
//-----------------------------------使用AsyncTask异步加载图片
public void loadBitmap(int resId, ImageView imageView) { BitmapWorkerTask task = new BitmapWorkerTask(imageView); task.execute(resId);}
三、缓存Bitmap(Caching Bitmaps)
1、使用内存缓存LruCache类(Use a Memory Cache)
2.3以后垃圾回收器,对于回收软引用和弱引用越来越厉害,往往,程序离out of memory 还很早弱引用或者软引用就被回收了。。
所以不建议使用软引用和弱引用。
下面的例子是使用 LruCache加载Bitmap
private LruCache<String, Bitmap> mMemoryCache;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(new MyView(this));int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024);int cacheSize = maxMemory/8; //缓存mMemoryCache = new LruCache<String, Bitmap>(cacheSize){@Overrideprotected int sizeOf(String key, Bitmap value) {return value.getByteCount()/1024; //缓存的大小 ,兆为单位}};}//往内存缓存中加入图片public void addBitmapToMemoryCache(String key,Bitmap bitmap){mMemoryCache.put(key, bitmap);}//通过key得到Bitmappublic Bitmap getBitmapFromMemoryCache(String key){return mMemoryCache.get(key);} public void loadImage(int resId ,ImageView mImageView){ final String imageKey = String.valueOf(resId); final Bitmap bitmap = getBitmapFromMemoryCache(imageKey); if (bitmap != null) { mImageView.setImageBitmap(bitmap); } else { mImageView.setImageResource(R.drawable.image_placeholder);//设置默认图片 //异步加载图片 BitmapWorkerTask task = new BitmapWorkerTask(mImageView); task.execute(resId); } }
2、使用磁盘缓存(Use a Disk Cache)
public static File getDiskCacheDir(Context context, String uniqueName) { final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() : context.getCacheDir().getPath(); return new File(cachePath + File.separator + uniqueName);}
四、管理Bitmap内存(Managing Bitmap Memory)
五、显示Bitmap到你的UI(Displaying Bitmaps in Your UI)
- 解决读取bitmap内存溢出问题
- 解决Android Bitmap内存溢出问题
- 解决Bitmap导致的内存溢出问题
- android按路径读取相册图片 完美解决Bitmap内存溢出问题
- Bitmap内存溢出问题
- 指定存储位置/Bitmap内存溢出解决/解决Bitmap无法序列化问题/输入流转Bitmap
- android Bitmap过大内存溢出问题的解决
- android中使用SoftRefrence解决Bitmap过大内存溢出问题
- android中使用SoftRefrence解决Bitmap过大内存溢出问题
- bitmap内存溢出的问题
- android解决bitmap内存溢出之二
- 解决POI读取Excel内存溢出的问题
- 解决POI读取Excel内存溢出的问题
- 解决POI读取Excel内存溢出的问题
- 解决POI读取Excel内存溢出的问题
- 解决POI读取Excel内存溢出的问题
- 解决内存溢出问题
- Android Bitmap内存管理,解决内存溢出问题(1)之自定义BitmapDrawable
- Xcode6 新建 Prefix Header
- storyboard 和 xib混用出现的layout布局有问题
- scala学习之map和tuple
- JPA入门例子(采用JPA的hibernate实现版本)
- 1030 - Discovering Gold (lightoj 1030 概率DP)
- 解决读取bitmap内存溢出问题
- swirl 3: Sequences of Numbers
- 我是菜鸟:MapReduce编程模型
- 使用GCD
- iOS学习(其他小控件的使用)
- Codeforces B - Berland National Library
- AndroidStudio单元测试——instrumentation
- 反转单向链表
- 在一个文件中有10G个整数,乱序排列,要求找出中位数