跟猜想的一样是OOM.一回来遇一不怎么熟悉的sb,给我气的....算了.....哥哥也是种种原因回的合肥.继续看问题.
这个地方的界面是这样的
划红线的地方是三个LinearLayout,每次onclick会PopupWindow一个界面用来提示用户.
在加载第二次弹出的PopupWindow时候出现了oom
我们来看下图片的大小
这三张图片原本大概在350KB左右,现在100多KB已经是经过压缩的了.
但是我们还是从基本开始搞,转jpg吧.
我们再去试一下,Note3已经没有问题了
如果单单是工作,到这也就结束了,但是老子气的要死,还是继续研究下去.
那我们来算一下大致在手机会占用多少内存吧.
bmp: 以高质量保存 用于计算机
jpg: 以良好的质量保存 用于计算机或者网络
png: 以高质量保存 用于计算机或者网络
图片的大小 = 图片的总像素 * 每个像素的大小
单色 :每个像素最多表示2种颜色 那么只需要一个长度为1的二进制位来表示 那么1个像素占1/8个byte
16色 :每个像素最多可以表示16种颜色, 0 - 15 0000-1111 那么只需要使用一个长度为4的二进制位来表示 那么一个像素占 1/2
256色 :每个像素最多可以表示256种 0-255 0000 0000-1111 1111 只需要使用一个长度为8的二进制位来表示 那么一个像素占1byte
24位 :R 1 byte 0 - 255
:G 1 byte 0 -255
:B 1 byte 0 -255 那么一个像素占3个byte
jpg:类似 rar压缩
png:也会按照特殊的算法进行压缩
我们在xml布局里面是这样写的
默认为ARGB_8888模式需要4个字节
第二次点击出现OOM的popup_two图片详细信息
那么他的内存占用大小为 图片的大小 = 图片的总像素 * 每个像素的大小
1080*1860*4=8035200字节
而报错的是8035212 多出来12个字节是保存图片信息的数据
那么换算成兆字节也就是7.6629639兆字节(mb)
那么再看
当这个图片加载到内存的时候为8035212 字节也就是7.6629639兆字节(mb)超出剩余的6498924空闲字节大小和6MB的head内存.然后内存溢出了.
那么说了那么多,虽然上面已经解决了问题,但是在这之外,我们还能做点什么呢?
1.布局中去android:background和android:src这些属性实际调用的是view.setBackgroundResource和view.setImageResource方法,这两个方法实际上是拿到资源ID再去获取资源的drawable。他们会decode图片后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。
实际上我们可以用decodeStream来替代,因为decodeStream直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间.另外我们可以设置图片的参数,例如设置为Bitmap.Config.RGB_565来减少内存开销。因为在android文档中描述Bitmap.Config.RGB_565每一个像素存在2个字节中,而默认的Bitmap.Config.ARGB_8888每一个像素则需要4个字节,理论上足足节省了一半空间。
布局文件中的android:background去掉,在java文件中来设置背景。
如下:
BitmapFactory.Options opt = newBitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
//获取资源图片
InputStream is = context.getResources().openRawResource(resId);
Bitmap bitmap = BitmapFactory.decodeStream(is,null, opt);
is.close();
returnnew BitmapDrawable(context.getResources(),bitmap);
2.缩放加载大图
iv = (ImageView) findViewById(R.id.iv);
//(1)获取手机的宽和高 windowmanager
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
screenWidth = wm.getDefaultDisplay().getWidth();
screenHeight = wm.getDefaultDisplay().getHeight();
//创建一个位图的配置参数
BitmapFactory.Options opts = new Options();
//不去真正的解析位图 返回no bitmap 但是能获取到图片的宽和高
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile("/mnt/sdcard/xxx.jpg", opts);
//(2)获取图片的宽度 和高度
int imgWidth = opts.outWidth;
int imgHeight = opts.outHeight;
System.out.println("图片的imgwidth:"+imgWidth+"-----"+imgHeight);
//(3)计算缩放比
int scale = 1;
int scalex = imgWidth / screenWidth;
int scaley = imgHeight / screenHeight;
if (scalex >=scaley && scalex >1) {
scale = scalex;
}
if (scaley > scalex && scaley >1) {
scale = scaley;
}
System.out.println("缩放比:"+scale);
//(4)按照真正计算出来的缩放比 进行显示图片
opts.inSampleSize = scale;
//(5)真正的加载位图
opts.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/xxx.jpg", opts);
//(6)把bitmap显示到图片上
iv.setImageBitmap(bitmap);
3.适度回收
if(bitmapObject.isRecycled()==false){ //如果没有回收
bitmapObject.recycle();
System.gc();
}
4.自定义最小head内存大小
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
//设置最小heap内存为6MB大小
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);
5.使用软引用了.
好了,气也消了,不写那么多了,其实工作只要正常跑起来基本问题就没什么了,只是偶尔回顾下基础知识对以后还是有帮助的.
解决OOM小记的更多相关文章
-
Android项目实战(十二):解决OOM的一种偷懒又有效的办法
在程序的manifest文件的application节点加入android:largeHeap=“true” 即可. 对,只需要一句话! 那么这行代码的意思是什么呢? 简单的说就是使该APP获取最大可 ...
-
什么是java OOM?如何分析及解决oom问题?
最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇,剩下的还需要 ...
-
什么是OOM?如何解决OOM问题!
1.什么是OOM? 程序申请内存过大,虚拟机无法满足我们,然后自杀了.这个现象通常出现在大图片的APP开发,或者需要用到很多图片的时候.通俗来讲就是我们的APP需要申请一块内存来存放图片的时候,系统认 ...
-
Android下缓存以及解决OOM问题
1 http://my.oschina.net/ryanhoo/blog/93285 开篇来个简单的后续的慢慢补充 2 http://www.apkbus.com/forum.php?mod=view ...
-
eclispe中解决OOM问题
-Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m
-
Android ImageSwitcher 配合Picasso解决内存溢出(OOM)问题
最近项目中用到了 ImageSwitcher 来实现图片切换,使用起来很简单,但发现当图片比较大(超过了3M)时,程序出现了内存溢出(OOM)问题而崩溃了. 原因就是图片太大了,显示到 ImageVi ...
-
一站式解决,Android 拍照 图库的各种问题.
在android开发中, 在一些编辑个人信息的时候,经常会有头像这么一个东西,就两个方面,调用系统相机拍照,调用系统图库获取图片.但是往往会遇到各种问题: 1.oom 2.图片方向不对 3.activ ...
-
viewPager--viewpager时,发生内存溢出OOM问题
两个问题:1.如果图片达到500kb每张,你这个划屏会有顿卡:2.快速滑动有出现0.几秒的白屏.图片越大,顿卡越明显. 回复parcool:500kb的背景算大的了,如果是想做图片墙,viewpage ...
-
Java 如何有效地避免OOM:善于利用软引用和弱引用
Java 如何有效地避免OOM:善于利用软引用和弱引用 想必很多朋友对OOM(OutOfMemory)这个错误不会陌生,而当遇到这种错误如何有效地解决这个问题呢?今天我们就来说一下如何利用软引用和弱引 ...
随机推荐
-
session失效
今天写页面时,使用了session 设置session后 跳转页面session就丢失 上网查了一下也没有很好的解决办法 也没有说原因. 在自己本地电脑上写了两个页面测试一下,完全正常.但是上传到服务 ...
-
websocket总结
一.WebSocket简介 WebSocket protocol是HTML5一种新的协议,WebSocket 是目前唯一真正实现全双工通信的服务器向客户端推送的互联网技术.WebSocket的出现使 ...
-
python 字典操作
字典的常用操作: clear 功能:清空字典 dict_li = {'users':'swht','age':'18',} dict_li.clear() 返回结果:dict_li {} copy 功 ...
-
AngularJs的$http使用随笔
AngularJs的$http服务是Angularjs自带的核心服务之一,用来与HTTP远程服务器交互. 关于$http使用,我体会的一下几点注意: 1.在使用是报“Uncaught Referenc ...
-
ADO.NET(完整修改和查询、实体类,数据访问类)
一.完整修改和查询 在编写c#语句时需考虑到用户体验,例如在编写修改语句时,需要考虑到输入的内容在数据库中是否能够找到. 中间变量运用. 1.先查 2.执行操作 完整修改语句: bool has = ...
-
C++:构造函数和析构函数能否为虚函数
原文:http://blog.csdn.net/xhz1234/article/details/6510568 C++:构造函数和析构函数能否为虚函数? 简单回答是:构造函数不能为虚函数,而析构函数可 ...
-
Tomcat源码学习一
这段时间工作不太忙,所以抽时间学习了TOMCAT, TOMCAT实际就是负责保持TCP连接传递到部署的项目中.浏览器实质就是TCP发送器.将用户的请求封装成TCP发送请求.当然格式是双方协定的.使用的 ...
-
riot.js教程【一】简介
Riotjs简介 Riotjs是一款简单的.优雅的.组件化UI前端开发框架: 他支持自定义标签(custom tags),拥有令人愉悦的语法,优雅的API和非常小的体积: 为什么需要一个新的界面库 前 ...
-
python基础-------模块与包(二)
sys模块.logging模块.序列化 一.sys模块 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时e ...
-
C#获取文件目录
Form1.cs using System;using System.Collections.Generic;using System.ComponentModel;using System.Data ...