### Bitmap与Android内存管理 在Android开发中,`Bitmap`对象是用于表示图像的主要类之一。然而,在处理大量或高分辨率图像时,不当的`Bitmap`管理常常会导致内存溢出问题,这严重影响了应用程序的性能和用户体验。接下来,我们将深入探讨如何有效地管理和优化`Bitmap`的使用,从而避免内存溢出。 #### 内存溢出原因分析 内存溢出(Out Of Memory,简称OOM)通常发生在应用消耗的物理内存超过了系统分配给它的最大内存限制。对于Android而言,当一个进程使用的本机或Java堆内存超过了一定阈值时,就会触发OOM错误。`Bitmap`作为占用内存较大的数据类型之一,往往是导致内存溢出的主要原因之一。 1. **图片加载方式**:如果直接将大尺寸的图片加载到内存中,而没有进行适当的压缩处理,很容易超出内存限制。 2. **重复创建Bitmap实例**:在应用程序中频繁地创建新的`Bitmap`对象而未及时回收旧的对象也会导致内存泄漏。 3. **缓存机制不当**:不合理的缓存策略也可能导致内存消耗过高。 #### 解决方案 为了有效解决这些问题,我们可以采取以下几种方法: ### 1. 使用适当的压缩比例 通过调整`BitmapFactory.Options`中的`inSampleSize`参数来控制加载的`Bitmap`的大小。这种方式可以显著减少内存消耗,同时保持较好的显示效果。 ```java InputStream is = this.getResources().openRawResource(R.drawable.pic1); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; // 需要真正解码 options.inSampleSize = 10; // 按照原图的十分之一大小加载 Bitmap btp = BitmapFactory.decodeStream(is, null, options); ``` 这里设置`inSampleSize`为10,意味着加载的图片宽度和高度将只有原始图片的十分之一。这样可以在一定程度上减轻内存负担。 ### 2. 显式释放Bitmap资源 为了避免内存泄漏,我们需要确保不再使用的`Bitmap`对象被正确回收。 ```java if (!bmp.isRecycled()) { bmp.recycle(); // 回收Bitmap占用的内存 System.gc(); // 建议垃圾回收 } ``` 注意,虽然调用`System.gc()`可以提示JVM进行垃圾回收,但并不能保证立刻执行垃圾回收。因此,我们应尽可能减少直接调用`System.gc()`。 ### 3. 合理使用缓存 缓存`Bitmap`可以提高性能,但也可能增加内存消耗。合理设计缓存策略非常重要。 ```java // 图片缓存 HashMap<Integer, Bitmap> bitmapCache = new HashMap<>(); if (bitmapCache.isEmpty() || !AppConst.bitmapCache.containsKey(position)) { bitmapCache.put(position, bm); System.out.println("-----------insert cache---------"); } // 释放Bitmap缓存中的资源 private void FreeBitmap(HashMap<Integer, Bitmap> cache) { if (cache.isEmpty()) { return; } for (Bitmap bitmap : cache.values()) { if (bitmap != null && !bitmap.isRecycled()) { bitmap.recycle(); System.out.println("=============recycle bitmap======="); } } cache.clear(); } ``` 上述代码展示了如何在需要的时候释放缓存中的`Bitmap`对象。 ### 4. 动态调整图片大小 在加载图片之前先获取其原始尺寸,并根据屏幕尺寸动态调整`Bitmap`的大小,以适应当前显示区域。 ```java BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inJustDecodeBounds = true; Bitmap bm = BitmapFactory.decodeFile(absolutePath, opt); // 获取图片原始宽高 int picWidth = opt.outWidth; int picHeight = opt.outHeight; WindowManager windowManager = getWindowManager(); Display display = windowManager.getDefaultDisplay(); int screenWidth = display.getWidth(); int screenHeight = display.getHeight(); // inSampleSize为加载图片时的缩放比例,值为2则图片的宽高变为原来的1/2 opt.inSampleSize = 1; if (picWidth > picHeight) { if (picWidth > screenWidth) { opt.inSampleSize = picWidth / screenWidth; } } else { if (picHeight > screenHeight) { opt.inSampleSize = picHeight / screenHeight; } } // 最终解码图片 opt.inJustDecodeBounds = false; bm = BitmapFactory.decodeFile(absolutePath, opt); // 在ImageView中显示Bitmap iv.setImageBitmap(bm); ``` 通过这些方法,我们可以有效地管理和优化`Bitmap`的使用,从而避免内存溢出问题的发生。这对于提升Android应用程序的稳定性和性能至关重要。
1. InputStream is = this.getResources().openRawResource(R.drawable.pic1);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 10; //width,hight设为原来的十分一
Bitmap btp =BitmapFactory.decodeStream(is,null,options);
2. if(!bmp.isRecycle() ){
bmp.recycle() //回收图片所占的内存
system.gc() //提醒系统及时回收
}
2.回收资源
(1)
//用来存放图片的缓存
HashMap<Integer, Bitmap> bitmapCache = new HashMap<Integer, Bitmap>();
//如果没有图片,或者已经存在
if(bitmapCache.isEmpty() || !AppConst.bitmapCache.containsKey(position)){
bitmapCache.put(position, bm);
System.out.println("-----------inset cache---------");
}
(2)定义FreeBitmap函数,在activity结束的时候,调用FreeBitmap函数,回收map中的资源
private void FreeBitmap(HashMap<Integer, Bitmap> cache){
if(cache.isEmpty()){
return;
}
for(Bitmap bitmap:cache.values()){
if(bitmap != null && !bitmap.isRecycled()){
bitmap.recycle();
System.out.println("=============recycle bitmap=======");
- 828784052012-08-13一般情况可以使用,但是现在我们的程序结构比较复杂!用不起来。
- 粉丝: 1
- 资源: 11
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 秋招信息获取与处理基础教程
- 程序员面试笔试面经技巧基础教程
- Python实例-21个自动办公源码-数据处理技术+Excel+自动化脚本+资源管理
- 全球前8GDP数据图(python动态柱状图)
- 汽车检测7-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar
- 检测高压线电线-YOLO(v5至v9)、COCO、Darknet、VOC数据集合集.rar
- 检测行路中的人脸-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、VOC数据集合集.rar
- Image_17083039753012.jpg
- 检测生锈铁片生锈部分-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、VOC数据集合集.rar
- 检测桌面物体-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar