Android高级开发第一讲--如何在Android应用中避免内存溢出OOM问题

本文深入探讨了Android应用中常见的内存溢出问题及其解决方案,包括使用软引用解决类问题、ListView优化、AQuery组件的使用以及如何避免内存溢出。通过实例演示了如何有效加载图片和使用AQuery组件简化内存管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

博客出自:http://blog.youkuaiyun.com/liuxian13183,转载注明出处! All Rights Reserved !


大家好,内存溢出问题,是做网络存取以及大型项目中一定会遇到的问题,所以搜集资料,翻译如下,希望对大家有所帮助!

另外介绍两个解决OOM的实际例子

通过使用软引用就可以轻松解决一些类似的问题:粗略讲述Java之软引用、弱引用和虚引用

ListView优化的例子--Android初级开发第八讲--ListView学习以及特性介绍



一、内存溢出

现在的智能手机内存已经足够大,但是对于一个应用程序来说智能手机当中稀缺的内存,仍然是应用程序的一大限制。在Android应用程序开发当中,最常见的内存溢出问题(OOM)是在加载图片时出现的,尤其是在不知道图片大小的情况下。
潜在的内存溢出操作主要包括以下几点:
1、从网络当中加载用户特定的图片。因为直到我们在下载图片的时候我们才知道图片的大小。
2、向Gallery加载图片。因为现在智能手机的摄像头有很高的分辨率,在加载图片的时候需要最图片进行处理,然后才能正常的使用。
请注意一点,Android系统是从系统全局的观念来分配内存以加载图片的,这就意味着,即使你的应用有足够大的内存可用,内存溢出问题(out of memroy,OOM)仍然可能出现,因为所有的应用共享一个加载图片的内存池(我们使用BitmapFactory进行解析)。
二、解决内存溢出问题
原文(Downsampling为了好理解,解释为,程序A)。程序A通过调整像素,同时使其均衡化来降低图片的分辨率。因为不管问题图片是因为太大而不能再手机上正常显现,这个图片都会缩短其宽度以在ImageView当中显示,当图片在ImageView当中显示时,我们会因为加载一些没有必要的原始图片而浪费掉内存。
因此,更加有效的加载图片的时机是在其初始化处理的时候。
以下是处理代码:
[html]  view plain copy print ?
  1.  private static Bitmap getResizedImage(String path, byte[] data, int targetWidth){  
  2.      BitmapFactory.Options options = new BitmapFactory.Options();  
  3.      options.inJustDecodeBounds = true;  
  4.      BitmapFactory.decodeFile(path, options);  
  5.      int width = options.outWidth;  
  6.      int ssize = sampleSize(width, targetWidth);  
  7.      options = new BitmapFactory.Options();  
  8.      options.inSampleSize = ssize;  
  9.       
  10.     Bitmap bm = null;  
  11.     try{  
  12.          bm = decode(path, data, options);  
  13.      }catch(OutOfMemoryError e){  
  14.          AQUtility.report(e);  
  15.      }  
  16.       return bm;  
  17.  }  
  18.  private static int sampleSize(int width, int target){  
  19.       
  20.      int result = 1;  
  21.        
  22.      for(int i = 0; i < 10; i++){  
  23.            
  24.          if(width < target * 2){  
  25.             break;  
  26.          }  
  27.            
  28.         width = width / 2;  
  29.         result = result * 2;       
  30.      }  
  31.     return result;  
  32. }  


三、AQuery
当在Android应用程序开发当中使用AQuery组件时,处理这个问题会变的更加的简单。
Down sample from the Internet

   1: String url = "http://farm6.static.flickr.com/5035/5802797131_a729dac808_b.jpg";            

   2: aq.id(R.id.image1).image(imageUrl, true, true, 200, 0);


Down sample image from File
   1: File file = new File(path);        
   2: //load image from file, down sample to target width of 300 pixels  
   3: aq.id(R.id.avatar).image(file, 300);
1、当从网络当中下载图片时,我们仅仅需要以下的几句代码:
2、当加载已有图片时,我们需要的代码如下:
原文地址:http://www.cnblogs.com/snowberg/archive/2012/04/21/2468507.html
http://blog.androidquery.com/2011/05/down-sample-images-to-avoid-out-of.html
四、Android Query组件介绍
Android Query是以开源项目,项目地址为:http://code.google.com/p/android-query/
其主要包括以下几个方面的代码:

详细信息请访问android query组件地址:http://code.google.com/p/android-query/

在 Java中,JavaVM拥有自动管理内存的功能,Java的GC能够进行垃圾回收,但是Android中如果ImageView使用过多的Bitmap的话,经常会报OOM(内存溢出)。

造成内存溢出及解决方案:
1.使用BitmapFactory.decodeStream替代createBitmap方法
原因是该方法直读取图片字节,调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap。

2.使用压缩读取技术
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imageSdUri, options); 
final int height = options.outHeight;
final int width = options.outWidth;
options.inSampleSize = 1;
int w = 320;
int h = 480;
h = w*height/width;//计算出宽高等比率
int a = options.outWidth/ w;
int b = options.outHeight / h;
options.inSampleSize = Math.max(a, b);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(imageSdUri, options);

3.及时释放Bitamp
Bitmap对象在不使用时,我们应该先调用recycle()释放内存,然后才它设置为null.虽然recycle()从源码上看,调用它应该能立即释放Bitmap的主要内存,但是测试结果显示它并没能立即释放内存。但是我它应该还是能大大的加速Bitmap的主要内存的释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值