### 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币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 扫描_5ded95f0811d407484dd3b1790de4e77.zip
- synapse数据库使用教程
- 数据库故障恢复策略:技术实现与代码实践
- java 猎头公司管理系统 招聘网站 招聘平台 项目源码 web ssm jsp【项目源码+数据库脚本+项目说明+软件工具】毕设
- C语言指针详解:用法与实例.docx
- 精奇科技远程PLC模块扩展
- DTW算法的MATLAB实现+项目源码+文档说明
- 前端 html + css + javascript(choise-card) .zip
- 使用孪生网络进行人脸识别《人脸识别考勤系统》+项目源码+文档说明
- 大厂面试高频考点解析-Java基础、微服务与数据库