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. ...
随机推荐
- Vysor:在电脑里控制你的安卓手机
Vysor是一款可以使用电脑操作安卓手机的谷歌浏览器插件,在chrome中安装了Vysor插件以后,用户就可以使用电脑打开手机的屏幕,在手机的屏幕界面中,用户不仅可以观看,甚至可以使用电脑直接操作手机 ...
- Mac wifi已打开但尚未连接到网络
把网络偏好设置 里面的询问新网络 关闭了 然后 重启电脑 试一下 应该就可以了
- 关于插件管理器Alcatraz
如何安装插件管理器Alcatraz:去github下载一个Alcatraz安装包,然后运行一下. 会弹出 记得选择左边的Load Bundle 退出Xcode 重新运行一下就OK 了. 然后就可以看到 ...
- 【读书笔记】iOS网络-理解错误源
考虑一个字节是如何从设备发往运程服务器以及如何从远程服务器将这个字节接收到设备,这个过程只需要几百毫秒时间,不过确要求网络设备都能正常工作才行.设备网络和网络互联的复杂性导致了分层网络的产生.分层网络 ...
- UIScrollView之轮转图片
在iOS开发中,经常会在APP首页看到多张图片进行轮换.刚开始做的时候,感觉很麻烦,不是很好做,查阅资料后,我总结了一下,自己封装了一个简单的轮转图片库: UIScrollView无限滑动 ,只需要三 ...
- org.apache packages can't be resolved in Eclipse解决方案
删除.m2仓库里面对应的jar包,重新Maven->update project
- CYQ.Data 轻量数据层之路 优雅V1.4 现世 附API帮助文档(九)
继上一版本V1.3版本发布到现在,时隔N天了:[V1.3版本开源见:CYQ.Data 轻量数据层之路 华丽V1.3版本 框架开源] N天的时间,根据各路网友的反映及自身的想法,继续修改优化着本框架,力 ...
- 从多个XML文档中读取数据用于显示webapi帮助文档
前言: 你先得知道HelpPageConfig文件,不知道说明你现在不需要这个,所以下文就不用看了,等知道了再看也不急.当然如果你很知道这个,下文也不用看了,因为你会了. 方法一: new XmlDo ...
- ASP.NET处理301重定向方法 带示例 (demo)
System.Web.HttpContext.Current.Response.Status = "301 Moved Permanently"; System.Web.HttpC ...
- java环境变量 windows centos 安装jdk
windows: 1.安装jdk,注意不是jre 2. 计算机→属性→高级系统设置→高级→环境变量,选择下面的那个系统环境变量 3. 系统变量→新建 JAVA_HOME 变量 . 变量值填写jdk的安 ...