Android加载图片时,对于分辨率小,配置低的机子,很容易发生OutOfMemoryError。手机的内存比图片的大很多,怎么会这样?

在设置Android虚拟机的内存时:

RAM:模拟器的内存空间

VM Heap:dalvik虚拟机最大占用内存,也就是单个进程的最大占用内存。

VM Heap高配的手机,可能有32M,64M,128M,而低配的手机,一般是16M,分辨率越大的手机,一般分配的也比较多。

Android系统对dalvik的vm heapsize作了硬性限制,当java进程申请的java空间超过阈值时,就会抛出OOM异常。也就是说RAM充足也会发生OOM的异常。

--------------------

VM Heap大小16mb,当应用加载一张大图时,加载图片所需要的内存空间不是按照图片大小算的,而是按照图片的像素点来算的。

图片像素点计算:

1张叫juhua.jsp的图片,大小1.27MB,分辨率:3840*2160,24位。

* Android保存图片像素信息,是用ARGB保存
 * A:0-255,需要一个长度为8的二进制数字,占用1个字节
 * R:0-255,需要一个长度为8的二进制数字,占用1个字节
 * G:0-255,需要一个长度为8的二进制数字,占用1个字节
 * B:0-255,需要一个长度为8的二进制数字,占用1个字节
3840*2160*4=33177600字节/1024/1024=31.640MB
超过了VM Heap的16MB,报内存溢出
10-27 06:16:27.645: I/dalvikvm-heap(1894): Forcing collection of SoftReferences for 33177612-byte allocation
10-27 06:16:27.645: E/dalvikvm-heap(1894): Out of memory on a 33177612-byte allocation.
10-27 06:16:27.655: E/AndroidRuntime(1894): Caused by: java.lang.OutOfMemoryError
************************************
解决方法:
按比例缩小图片,再加载。
现有手机屏幕分辨率 320*480
宽比:3840/320=12
高比:2160/480=4
选择比例大的数字12
缩放后再设置,就不会溢出了。
31.640MB/12=2.64mb
代码例子:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" ><Buttonandroid:id="@+id/btn1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="点击加载大图片(OOO)"android:onClick="loadPic"/><Buttonandroid:id="@+id/btn2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/btn1"android:text="点击缩放加载大图片"android:onClick="scaleLoadPic"/><ImageView android:id="@+id/iv_pic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/btn2"/></RelativeLayout>
package com.example.loadbigpic;import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.widget.ImageView;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void loadPic(View v){/** BitmapFactory.decodeResource(?,?)* 这个带两个参数的方法:第一个参数是包含你要加载的位图资源文件的对象(一般写成 getResources()就ok了);* 第二个时你需要加载的位图资源的Id。BitmapFactory.decodeResource(?,?,?)带三个参数的方法:前两个和上面的方法一样。第三个参数应该是对你要加载的位图是否需要完整显示,如果你只需要部分,可以在这里定制。*/Bitmap bm=BitmapFactory.decodeResource(getResources(),R.drawable.juhua);ImageView iv_pic=(ImageView) findViewById(R.id.iv_pic);iv_pic.setImageBitmap(bm);}public void scaleLoadPic(View v){Options opts=new Options();//默认为false,设为true,则decoder返回null,//即BitmapFactory.decodeResource(getResources(),R.drawable.juhua,opts);返回null//但会返回图片的参数的信息到Options对象里//不解析图片到内存里opts.inJustDecodeBounds=true;BitmapFactory.decodeResource(getResources(),R.drawable.juhua,opts);//获取图片的宽,高int imageWidth=opts.outWidth;int imageHeigth=opts.outHeight;//获取屏幕的高宽Display dp=getWindowManager().getDefaultDisplay();//在高版本里有新的方法获取,但图片加载是常用功能,要兼容低版本,所以过时了也用int screenWidth=dp.getWidth();int screenHeight=dp.getHeight();//计算缩放比例int scale=1;int scaleWidth=imageWidth/screenWidth;int scaleHeight=imageHeigth/screenHeight;//取缩放比例,取那个大的值if(scaleWidth>=scaleHeight && scaleWidth>=1){scale=scaleWidth;}else if(scaleWidth<scaleHeight && scaleHeight>=1){scale=scaleHeight;}//设置缩放比例opts.inSampleSize=scale;opts.inJustDecodeBounds=false;Bitmap bm=BitmapFactory.decodeResource(getResources(),R.drawable.juhua,opts);ImageView iv_pic=(ImageView) findViewById(R.id.iv_pic);iv_pic.setImageBitmap(bm);}}

Android加载大图片不OutOfMemoryError相关推荐

  1. 【转载】Android加载大图片OOM异常解决

    官方资料: https://developer.android.com/topic/performance/graphics/load-bitmap 思路 先测试未知来源图片的尺寸和MIME文件类型; ...

  2. Android加载大图片OOM异常解决

    Android加载大图片OOM异常解决 参考文章: (1)Android加载大图片OOM异常解决 (2)https://www.cnblogs.com/jevan/archive/2012/07/05 ...

  3. Android手机内存图片读取,有效解决Android加载大图片内存溢出的问题

    今天在交流群里,有人问我他经常遇到加载图片时内存溢出的问题,遇到的情况还是在自己的测试机或者手机里没有问题,做好了, 到了客户手机里就内存溢出了.其实有时候不同的手机和不同的系统对内存的要求不一样,尤 ...

  4. Android 加载大图片

    我们在做开发的时候总是会不可避免的遇到加载图片的情况,当图片的尺寸小于ImageView的尺寸的时候,我们当然可以很happy的去直接加载展示.但是如果我们要加载的图片远远大于ImageView的大小 ...

  5. 解决Android 加载大图片OOM

    图片在Android 占用内存计算 假如一张图的像素为100×200,那么他在内存中占用的内存为: 100×200(像素点) × 4(每个像素点占用的内存,默认为4.) public Bitmap.C ...

  6. Android加载大图片(压缩)

    转载自http://blog.csdn.net/junjx/article/details/7798604 在Android开发中,我们经常需要加载图片.但是图片的尺寸往往会很大,如果我们要的是比较小 ...

  7. Android 加载本地图片(文件管理器中的图片墙)

    Android 加载本地图片(文件管理器中的图片墙) --关于图片墙的一些感悟与疑问,希望大家共同探讨. (By伊叶也) 图片显示及监听 1.图片显示:基本上就5种显示形式(如果同时嵌入5种形式,采用 ...

  8. 关于 android 加载 res 图片 out of memory 问题 解决 同样适用于 sd卡图片

    2019独角兽企业重金招聘Python工程师标准>>> 发现android 加载res图片如果过多也会崩溃 android 也是使用 Bitmap  bm = BitmapFacto ...

  9. Android 高效加载大图片

    来源:http://www.open-open.com/lib/view/open1389755918242.html 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状 ...

最新文章

  1. java反射 获取参数名_java
  2. 目标检测旋转增强源码
  3. 45 Ansible Play-books模式
  4. 反编译android的apk
  5. 文件服务器的迁移(包括权限)
  6. (转)K-近邻算法(KNN)
  7. 神经网络十大学习率衰减提效策略
  8. maven springboot 除去指定的jar包_1. Spring Boot概述
  9. 面试步步受挫,在打击中成长
  10. linux 根目录read only,linux – 使readonly / etc可写
  11. 解决miner.start() 返回null
  12. Github上点赞最多的10个Python项目(2020年3月)
  13. Windows Server 2008设置远程桌面连接数
  14. 【渝粤教育】广东开放大学 公文写作选读 形成性考核 (30)
  15. java线程期末考试_mooc课程 java 期末考试试卷
  16. 电脑安装系统时提示“找不到硬盘”如何解决
  17. 计算机软件安装包后缀名,请问以 ISO 为后缀名的是什么文件,用什么软件可以打开?...
  18. 关于一维数组(小朋友都能明白的一维数组超详细介绍)
  19. 我们为什么来到这个世界上?--黄金雄(杰西)
  20. java实现多态在工资系统中的应用:给出一个根据雇员类型,利用多态性完成工资单计算的程序。

热门文章

  1. ironpython this_IronPython sys._getframe not found
  2. java把对象转成图片格式转换器安卓版,java 万能图片格式转换
  3. java基础知识点_JAVA基础知识
  4. ad怎么批量改元器件封装_AD6.8的原理图中如何批量修改封装?
  5. python爬取哔哩哔哩视频_Python实现视频爬取下载
  6. 语言爬虫字段为空_我为什么建议前端将Python 作为第二语言?
  7. UnicodeEncodeError: 'gbk' codec can't encode character '\xeb' in position 20: illegal multibyte sequ
  8. JDK源码解析之java.util.Iterator和java.lang.Iterable
  9. go设计模式之单例模式
  10. 问题 D: 最小生成树II