Android中一张图片加载后所占用内存大小的获取与测试
Android程序中一旦加载的图片比较多,就有可能出现Out of Memory而导致程序崩溃。这个一方面是因为Android系统本身对于每个单独的进程有内存大小的限制(有16M,64M,128M,256M等等),另一方面是因为Android系统对于图片资源的垃圾回收比较慢(文章http://jiangnane.com/index.php/archives/230中对Android源码进行了分析,发现Android的setImageViewBitmap(Bitmap bm)方法的源码中没有建立新的bitmap,而是用引用的方式来使用bm的,这就导致bm被多处引用)。
那一幅图片占用的内存大概多大呢?这篇博文主要是记录了我在测试一副图片占用字节数时查阅的一些资料和测试结果。
1.图片的表示方法
Android的Bitmap.Config给出了bitmap的一个像素所对应的存储方式,有RGB_565,ARGB_8888,ARGB_4444,ALPHA_8四种。RGB_565表示的是红绿蓝三色分别用5,6,5个比特来存储,一个像素占用了5+6+5=16个比特。RGB_8888表示红绿蓝和半透明分别用8,8,8,8个比特来存储,一个像素占用了8+8+8+8=32个比特。这样的话如果图片是以RGB_8888读入的,那么占用内存的大小将是RGB_565读入方式的2倍。
通常我们给Imagview加载图片是通过setDrawable或者在xml文件中用android:src来设置,从BitmapFactory.Options.inPreferredConfig的说明文档可以看出,默认的加载图片大小的方式是以RGB_8888读入的。
2.获取bitmap占用的字节数
API 12以上可以直接获取,以下则是通过获取高和行所占字节相乘得到的。
protected int sizeOf(Bitmap data) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
return data.getRowBytes() * data.getHeight();
} else {
return data.getByteCount();
}
}
来源:http://stackoverflow.com/a/2408164/1767800
3.以RGB_565方式读入图片
public Bitmap readBitMap(Context context, int resId){
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
//获取资源图片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is,null,opt);
}
参考:http://blog.csdn.net/yangyangiud/article/details/12835885
4.获取ImageView和其中drawable的大小
获取ImageView和其中drawable大小需要在onWindowFocusChanged获取,在oncreate中返回的结果是0.
public void onWindowFocusChanged(boolean hasFocus){
ImageView imageView=(ImageView)findViewById(R.id.test1);
Log.v("Testresult","width= "+imageView.getWidth()+" height= "
+imageView.getHeight());
Log.v("Testresult","drawawidth= "+imageView.getDrawable().getBounds().width()+
" drawableheight= "
+imageView.getDrawable().getBounds().height());
}
参考:http://stackoverflow.com/a/15128508/1767800
5.Oncreate()中的测试代码
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView=(ImageView)findViewById(R.id.test1);
Drawable drawable = imageView.getDrawable();
int bitmapWidth = drawable.getIntrinsicWidth(); //this is the bitmap's width
int bitmapHeight = drawable.getIntrinsicHeight(); //this is the bitmap's height
Log.v("Testresult","bitmapwidth= "
+bitmapWidth+" bitmapHeight= "+bitmapHeight);
Bitmap bitmap=((BitmapDrawable)imageView.getDrawable()).getBitmap();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
Log.v("Testresult","bitmap bytes are"+bitmap.getRowBytes()*bitmap.getHeight());
} else {
Log.v("Testresult", "bitmap bytes are"+bitmap.getByteCount());
}
bitmap=readBitMap(this, R.drawable.pic_1000_562);
//api 12之上可以直接获取bitmap所占用的字节数
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
Log.v("Testresult","bitmap bytes are"+bitmap.getRowBytes()*bitmap.getHeight());
} else {
Log.v("Testresult", "bitmap bytes are"+bitmap.getByteCount());
}
}
6.测试结果

其中原图片大小是1000*562,手机屏幕的分辨率是480*800.从图中可以看出,采用android:src的加载方式占用的字节数是采用RGB_565加载方式的2倍。且1124000=2*1000*562字节。并且虽然在手机中显示的时候bitmap被缩小显示了,但是drawable的长宽所占字节是和图片的尺寸相一致的。
Android中一张图片加载后所占用内存大小的获取与测试的更多相关文章
- Android开发中如何解决加载大图片时内存溢出的问题
Android开发中如何解决加载大图片时内存溢出的问题 在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给 ...
- arcgis android 中shapefile的加载
前言 本文为大家分享arcgis android 中shapefile的加载,默认你有java环境,懂一定的android基础知识,默认你已经安装android studio.如缺乏以上环境和知识,请 ...
- 解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题
下面两种现象,用同一种方法解决 1.解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题 2.突然有一天首页访问图片很慢,至少隔20多秒所有图片才会出来.(解析:app使 ...
- Android中的动态加载机制
在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...
- Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案
我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...
- Android中的Glide加载图片
注意:在Android Studio的项目的build.gradle中添加: compile 'com.github.bumptech.glide:glide:3.6.1' 然后同步一下 目录: 使用 ...
- Android中的分页加载
//----------------------MainActivity中--------------------------------------------------- package com ...
- Android中使用POI加载与显示word文档
最近打算实现一个功能:在Android中加载显示Word文档,当然这里不是使用外部程序打开.查看一些资料后,打算采用poi实现,确定了以下实现思路: 将ftp中的word文档下载到本地. 调用poi将 ...
- Android中的缩略图加载-不浪费一点多余的内存
1. Why,为什么要加载缩略图? 有的时候不需要展示原图,只需展示图片的缩略图,可以节省内存.比如:网易新闻中的图片浏览,左边展示的小狮子图片就是一个缩略图,点击这个图片,才会展示原图. 2. ...
随机推荐
- ARC下内存泄露问题
ARC下内存泄露问题 ARC下内存泄露问题,有需要的朋友可以参考下. iOS提供了ARC功能,很大程度上简化了内存管理的代码. 但使用ARC并不代表了不会发生内存泄露,使用不当照样会发生内存泄露. 下 ...
- iOS之 C++与oc混编
声明:本文只是随笔,自己做个笔记方便以后查阅如要转载,注明出处.谢谢! 2016年第一篇随笔!!! 由于最近要搞一个项目用到c++的一些api所以要混编,于是就记录下这个过程中的一些细节上的东西! O ...
- java文件复制函数
在写代码中,经常会需要复制文件.这时候就可以把这些函数放到工具类里面. 下面是一个复制文件的函数: public class CopyFileUtil { private static String ...
- php 图片上传 使用微秒做文件名
$m = microtime ();$mtime = explode(' ' ,$m);$mtime1 = $mtime[1];$mtime2 = substr($mtime[0], 2, 6);$p ...
- nodejs 小爬虫
编写爬虫示例: var http = require('http'); var cheerio = require('cheerio'); var url = 'http://www.cnblogs. ...
- SYN Flood应如何应对
1 什么是SYN Flood攻击 在TCP三次握手时,服务器接收客户端的SYN请求,操作系统将为该请求分配一个TCP(Transmission Control Block),服务器返回一个SYN/AC ...
- Linux中如何解压iso类型文件
在Linux下如何解压iso类型的文件呢? 可以使用mount命令来处理 [root@DB-Server tmp]# ls /tmp/rhel-server-5.7-x86_64-dvd.iso /t ...
- dos2unix用法
windows下编写的脚本,上传到linux上执行,有时会出现莫名其妙的结果,也是折腾了半天才找出原因,windows和linux有些编码不同,经dos2unix处理后,结果一切正常man dos2u ...
- HDU 4866 Shooting(持久化线段树)
view code//第二道持久化线段树,照着别人的代码慢慢敲,还是有点不理解 #include <iostream> #include <cstdio> #include & ...
- Hive分析hadoop进程日志
想把hadoop的进程日志导入hive表进行分析,遂做了以下的尝试. 关于hadoop进程日志的解析 使用正则表达式获取四个字段,一个是日期时间,一个是日志级别,一个是类,最后一个是详细信息, 然后在 ...