Android加载大图片不OutOfMemoryError

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

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

RAM:模拟器的内存空间

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

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);}}







本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/539997.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

任务计划、chkconfig工具、systemd管理服务、unit、target

比如备份数据或者重启服务。 crontab -u、-e、-l、-r&#xff08;删除&#xff09; 格式&#xff1a;分 时 日 月 周 user command 文件/var/spool/cron/username 分范围0-59&#xff0c;时范围0-23&#xff0c;日范围1-31&#xff0c;月范围1-12&#xff0c;周1-7 可用格式1-5…

vue打卡日历_Vue日历

new Vue({el: ‘#calendar‘,data: {currentDay: 1,currentMonth: 1,currentYear: 1970,currentWeek: 1,days: [],addDay: [],},created: function() {this.initData(null);var $this this;//请求数据$.ajax({url: "这里填接口名称",type: "POST",data: {…

android Intent机制详解

原文出处&#xff1a;http://blog.csdn.net/t12x3456/article/details/7688154 什么是Intent Intent是一种运行时绑定&#xff08;run-time binding&#xff09;机制&#xff0c;它能在程序运行过程中连接两个不同的组件。通过Intent&#xff0c;你的程序可以向Android表达某种…

python基本数据类型(四)-集合与运算符-python3笔记

1.集合 2.字典 3.运算符优先级 1.集合 创建&#xff1a;() set() 注意&#xff1a;创建空的集合要用set() 特点&#xff1a;元素唯一&#xff0c;无序 运算&#xff1a; &&#xff08;交集&#xff09; |&#xff08;并集&#xff09; -&#xff08;差集&#xff0…

Android的权限

Android有四种权限&#xff1a; 1、Permission 权限 2、Root权限 3、Bootloader的解锁 4、Radio(基带)解锁 ------------------------------------ 1、Permission 我们在开发中经常使用到 Permission 权限&#xff0c;即一系列"Android.Permission.*"对象。…

hive2 java连接_用Java代码通过JDBC连接Hiveserver2

1.在终端启动hiveserver2#hiveserver22.使用beeline连接hive另外打开一个终端&#xff0c;输入如下命令(xavierdb必须是已经存在的数据库)#beeline -u jdbc:hive2://localhost:10000/xavierdb -n hive -p hive3.添加maven依赖org.apache.hivehive-jdbc1.1.0junitjunit4.9org.ap…

java 向上抛异常_Java 异常的处理方式throws

在昨天的文章《Java 异常的分类与处理》中我们简单地了解了一下在方法声明的位置上使用throws关键字向上抛出异常&#xff0c;下面深入讲解异常的第一种处理方式throws。下面深入讲解异常的第一种处理方式throws。看以下例子&#xff1a;import java.io.*;public class Excepti…

Jquery mobile 解决IOS9selectli闪退问题

升级IOS9后&#xff0c;JQuery mobile 出现了个bug问题。<select>&#xff0c;<ul><li></li></ul> 出现闪退。 解决方法&#xff1a; 必须加在 jquery.js 和 jquerymobile.js 中间 <script src"......../...../jquery-2.0.0.min.js&qu…

JAVA通过SSL证书创建MS AD账户及设置密码

近期由于工作需要整理一下自动化的东西&#xff0c;因为公司去年上线了OA&#xff0c;所以公司的入职系统会提交用户的信息到IT部门&#xff0c;最早的做法是入职到了&#xff0c;IT部门收集用户信息在AD中创建对应的用户信息&#xff0c;所以为了提高管理员的工作效率&#xf…

java 实体类规范_实体类的规范

1.Boolean类型1.1.使用Boolean类型,而不是Byte类型1.2.数据库字段名使用is_开头1.3.实体类字段名不使用is开头例子/*** 是否为新消息*/Column(name "is_new_message", nullable false)private Boolean newMessage;2.Enum类型1.使用Convert注解, 并指定coverter类例…

01电话拨号器

实例非常简单&#xff0c;意在体验Android的Intent&#xff0c;用户权限。 Intent 见 http://blog.csdn.net/zengmingen/article/details/49586045 用户权限 见 http://blog.csdn.net/zengmingen/article/details/49586569 --------------------------------------------------…

微信小程序笔记六模块化 —— module.exports

微信小程序中所有 js 文件作用域皆为独立的&#xff0c;每一个 js 文件即为一个模块。模块与模块之间的引用通过 module.exports 或 exports 对外暴露接口。 注意&#xff1a; exports 是 module.exports 的一个引用&#xff0c;因此在模块里边随意更改 exports 的指向会造成未…

java常用的统计_(OJ)Java常用类-统计数字次数

统计数字次数Problem Description命令行输入一个由数字组成的任意字符串,统计出每个数字出现的次数。Input Description1239586838Output Description0 counts:01 counts:12 counts:13 counts:24 counts:05 counts:16 counts:17 counts:08 counts:39 counts:1解题代码import ja…

02发送短信

使用SmsManager发送短信java.lang.Object ↳android.telephony.SmsManagerManages SMS operations such as sending data, text, and pdu SMS messages. Get this object by calling the static method SmsManager.getDefault().管理短信操作&#xff0c;如发送数据&#xff…

Python运行环境与异常处理

Python的命令格式&#xff1a; python [option] ... [-c cmd | -m mod | file | -] [arg] ... 选项描述-J 启动将从Python3中删除或更改某些功能的警告 -B阻止在导入时创建.pyc或.pyo文件-E忽略环境变量-h打印所有可用命令行选项的列表-i在程序执行后进入交互模式-m module以脚…

Java应用一般架构

原文链接&#xff1a;http://www.iteye.com/news/31115 当我们架设一个系统的时候通常需要考虑到如何与其他系统交互&#xff0c;所以我们首先需要知道各种系统之间是如何交互的&#xff0c;使用何种技术实现。 1. 不同系统不同语言之间的交互 现在我们常见的不同系统不同语…

Mac MongoDB未正常关闭导致重启失败

你可以删除掉mongod.lock文件&#xff0c;然后重新启动&#xff0c;如果还是不可以&#xff0c;你可以查看一下进程&#xff0c;然后杀掉&#xff1a; ps -aef | grep mongo sudo kill 1076 再重启数据库即可。

微信企业号让IOS不要识别数字为电话号码的方法

最近在开发一个联系人查看功能时&#xff0c;发现IOS端把 8位&#xff0c;11位的数字识别为了 电话号码。 本来是黑色的样式&#xff0c;变成了蓝色的样式&#xff0c;还添加了下划线。点击一下&#xff0c;还可以拨打电话。 这个问题要改&#xff0c;解决方法很简单&#xf…

powerdns与nginx结合实现以域名和IP方式访问web服务器80端口时分别跳转到不同页面...

1.powerdns设置 2.内部网站介绍 web服务器采用nginx&#xff0c;内网dns采用powerdns. 想实现的功能如下 通过ip访问时跳转到A页面&#xff0c;通过域名访问时&#xff0c;让其跳转到B页面。两种方式的端口均为80. 页面A对应的nginx配置 server { listen 80; …

Installation error code: -103签名不一致错误

调用Android系统的PackageInstallerActivity进行app安装时&#xff0c;报Installation error code: -103 错误。 原因是&#xff1a;签名问题。 可能是 1、正安装的应用没用签名 2、正安装的应用与已安装的应用包相同&#xff0c;但签名不同。 解决方法&#xff1a; 1、给…