Android加载大图片OOM异常解决
来源:互联网 发布:百度黑洞特效js 编辑:程序博客网 时间:2024/06/11 13:46
项目用到加载大图片,app老是出现OOM异常,总结了几点经验,供参考。
1、手动干涉dalvik的堆内存处理效率:
1 private final static float TARGET_HEAP_UTILIZATION = 0.75f;2 //for same activity3 public void onCreate()4 {5 …………6 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 7 …………8 }
2、手动指定Android堆大小:
1 private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ; 2 //for same activity3 public void onCreate()4 {5 …………6 VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。当然对于内存吃紧来说还可以通过手动干涉GC去处理 7 …………8 }
3、手动指定回收内存,指定gc:
1 if(bitmap!=null && !bitmap.isRecycled())2 {3 bitmap.recycle();4 System.gc();5 }
4、图片必须进行缩放,不然多半会出OOM:
1 /** 2 * @param url 3 * 图片的url 4 * @param sc 5 * ,显示的像素大小 6 * @return 返回指定RUL的缩略图 7 * 8 * @author jevan 2012-7-3 9 * 10 */11 public static Bitmap loadImageFromUrl(String url, int sc)12 {13 14 URL m;15 InputStream i = null;16 BufferedInputStream bis = null;17 ByteArrayOutputStream out = null;18 19 if (url == null)20 return null;21 try22 {23 m = new URL(url);24 i = (InputStream) m.getContent();25 bis = new BufferedInputStream(i, 1024 * 4);26 out = new ByteArrayOutputStream();27 int len = 0;28 29 while ((len = bis.read(isBuffer)) != -1)30 {31 out.write(isBuffer, 0, len);32 }33 out.close();34 bis.close();35 } catch (MalformedURLException e1)36 {37 e1.printStackTrace();38 return null;39 } catch (IOException e)40 {41 e.printStackTrace();42 }43 if (out == null)44 return null;45 byte[] data = out.toByteArray();46 BitmapFactory.Options options = new BitmapFactory.Options();47 options.inJustDecodeBounds = true;48 BitmapFactory.decodeByteArray(data, 0, data.length, options);49 options.inJustDecodeBounds = false;50 int be = (int) (options.outHeight / (float) sc);51 if (be <= 0)52 {53 be = 1;54 } else if (be > 3)55 {56 be = 3;57 }58 options.inSampleSize = be;59 Bitmap bmp =null;60 try61 {62 bmp = BitmapFactory.decodeByteArray(data, 0, data.length, options); //返回缩略图63 } catch (OutOfMemoryError e)64 {65 // TODO: handle exception66 MainActivity.print("Tile Loader (241) Out Of Memory Error " + e.getLocalizedMessage()); 67 68 System.gc();69 bmp =null;70 }71 return bmp;72 }
把上面几条全部用上,OOM的异常基本上能完全避免!!!
以下内容为转载,收藏。
1 //我们在BitmapManager.instance().decodeFile对图片进行解码,生成Bitmap的时候,我们会发现很多大图片会报OutOfMemoryError的错误,这个时候我们需要改变options里面的一些参数来解决这个问题,不然我们程序就跑不下去了。最简单的方法就是改变options.inSampleSize这个参数,把它增大,就可以解决很多图片OutOfMemoryError的问题。 2 //下面是一个使用了这个方式的代码 3 public static Bitmap makeBitmap(String path, int minSideLength, int maxNumOfPixels, BitmapFactory.Options options) 4 { 5 Bitmap b = null; 6 Log.i(TAG, "makeBitmap : path = " + path); 7 if (path == null) 8 return null; 9 File f = new File(path);10 11 //try {12 // b = BitmapManager.instance().decodeFile(f, null);13 //} catch (OutOfMemoryError ex) {14 // Log.e(TAG, "Got oom exception, we may try one more time, using Options:" + ex.getMessage());15 if (options == null)16 {17 options = new BitmapFactory.Options();18 }19 20 try21 {22 options.inJustDecodeBounds = true;23 BitmapManager.instance().decodeFile(f, options);24 if (options.mCancel || options.outWidth == -1 || options.outHeight == -1)25 {26 return null;27 }28 options.inSampleSize = computeSampleSize(options, minSideLength, maxNumOfPixels);29 options.inJustDecodeBounds = false;30 options.inDither = true;31 options.inPreferredConfig = null;//Bitmap.Config.ARGB_8888;32 33 b = BitmapManager.instance().decodeFile(f, options);34 } catch (OutOfMemoryError ex2)35 {36 Log.e(TAG, "Got oom exception when retry the 2nd time,options.inSampleSize= " + options.inSampleSize + " minSideLength = "37 + minSideLength + " maxNumOfPixels =" + maxNumOfPixels, ex2);38 try39 {40 options.inSampleSize += 1;41 options.inJustDecodeBounds = false;42 options.inDither = true;43 options.inPreferredConfig = null;44 b = BitmapManager.instance().decodeFile(f, options);45 } catch (OutOfMemoryError e)46 {47 Log.e(TAG, "Got oom exception when retry the 2nd time,options.inSampleSize= " + options.inSampleSize + " minSideLength = "48 + minSideLength + " maxNumOfPixels =" + maxNumOfPixels, e);49 try50 {51 options.inSampleSize += 1;52 options.inJustDecodeBounds = false;53 options.inDither = true;54 options.inPreferredConfig = null;55 b = BitmapManager.instance().decodeFile(f, options);56 } catch (OutOfMemoryError ex)57 {58 Log.e(TAG, "Got oom exception when retry the 2nd time,options.inSampleSize= " + options.inSampleSize59 + " minSideLength = " + minSideLength + " maxNumOfPixels =" + maxNumOfPixels, ex);60 return null;61 }62 }63 }64 65 //} 66 return b;67 }
1 //另外一处代码 2 public static Bitmap getBitpMap(InputStream is) 3 { 4 ParcelFileDescriptor pfd; 5 try 6 { 7 pfd = getContentResolver().openFileDescriptor(uri, "r"); 8 } catch (IOException ex) 9 {10 return null;11 }12 java.io.FileDescriptor fd = pfd.getFileDescriptor();13 BitmapFactory.Options options = new BitmapFactory.Options();14 //先指定原始大小 15 options.inSampleSize = 1;16 //只进行大小判断 17 options.inJustDecodeBounds = true;18 //调用此方法得到options得到图片的大小 19 BitmapFactory.decodeFileDescriptor(fd, null, options);20 //BitmapFactory.decodeStream(is, null, options);21 //我们的目标是在800pixel的画面上显示。 22 //所以需要调用computeSampleSize得到图片缩放的比例 23 options.inSampleSize = computeSampleSize(options, 800);24 //OK,我们得到了缩放的比例,现在开始正式读入BitMap数据 25 options.inJustDecodeBounds = false;26 options.inDither = false;27 options.inPreferredConfig = Bitmap.Config.ARGB_8888;28 29 //根据options参数,减少所需要的内存 30 // Bitmap sourceBitmap = BitmapFactory.decodeFileDescriptor(fd, null, options);31 Bitmap sourceBitmap = BitmapFactory.decodeStream(is, null, options);32 return sourceBitmap;33 }34 35 //这个函数会对图片的大小进行判断,并得到合适的缩放比例,比如2即1/2,3即1/3 36 static int computeSampleSize(BitmapFactory.Options options, int target)37 {38 int w = options.outWidth;39 int h = options.outHeight;40 int candidateW = w / target;41 int candidateH = h / target;42 int candidate = Math.max(candidateW, candidateH);43 if (candidate == 0)44 return 1;45 if (candidate > 1)46 {47 if ((w > target) && (w / candidate) < target)48 candidate -= 1;49 }50 if (candidate > 1)51 {52 if ((h > target) && (h / candidate) < target)53 candidate -= 1;54 }55 //if (VERBOSE)56 Log.v(TAG, "for w/h " + w + "/" + h + " returning " + candidate + "(" + (w / candidate) + " / " + (h / candidate));57 return candidate;58 }
0 0
- Android加载大图片OOM异常解决
- Android加载大图片OOM异常解决
- 【OOM】Android加载大图片OOM异常解决
- Android 加载大图片造成OOM异常解决方法
- Android中加载大图片放置OOM异常
- BitmapFactory.Options 解决加载大图片OOM
- 解决加载大图片oom处理
- BitmapFactory.Options 解决加载大图片OOM
- BitmapFactory.Options 解决加载大图片OOM
- BitmapFactory.Options 解决加载大图片OOM
- BitmapFactory.Options 解决加载大图片OOM
- 【Android】大图片加载时OOM
- android 高效加载大图片,避免OOM
- Android 高效加载大图片避免OOM
- Android 大图片加载 避免OOM
- Android高效加载大图片,防止OOM
- Android 高效加载大图片避免OOM
- android显示加载大图片OOM问题
- 关于reviewboard汉化
- rhel6安装VNCserver用相关rpm包及相关安装说明
- grub引导fedora16 使用本地安装
- MINA连接方式
- ControlPoint.java文件学习笔记
- Android加载大图片OOM异常解决
- Elf文件格式学习笔记
- 取当前运行Activity的名称
- 黑马程序员----java之面向对象(上)
- Dlna相关开源项目收集整理
- 给我的当前RHEL6新增一块硬盘!
- RHEL6单用户模式切换
- 移动端EDM邮件营销策略分析
- 不完全总结linux下c访问http