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. ...
随机推荐
- Atitti.java android反编译解决方案-----虚拟机方案
Atitti.java android反编译解决方案-----虚拟机方案 哈哈,终极解决方案是虚拟机...c++也可以反编译为汇编代码,但无需担心,因为读懂汇编太麻烦..只要不能拿到c++源码就可.. ...
- 自定义JSP标签库及Properties使用
自定义JSP标签库及Properties使用 自定义JSP标签 自定义JSP标签技术是在JSP 1.1版本中才出现的,它支持用户在JSP文件中自定义标签,这样可以使JSP代码更加简洁. 这些可重用的标 ...
- android加固系列—3.加固前先学会破解,静态修改so
[版权所有,转载请注明出处.出处:http://www.cnblogs.com/joey-hua/p/5138585.html] 项目jni的关键代码(项目地址见文章底部),获取当前程序的包名com. ...
- Net.Sf.Json java Object to JsonObject
public class People{ private String name; public void setName(String name){ this.name = name; } publ ...
- Java核心:类加载和JVM内存的分配
类的加载: 指的是将class文件的二进制数据读入到运行时数据区(JVM在内存中划分的) 中,并在方法区内创建一个class对象. 类加载器: 负责加载编译后的class文件(字节码文件)到JVM(J ...
- OC中的私有变量和description
.OC中的私有变量 在类的实现即.m @implementation中也可以声明成员变量,但是因为在其他文件中通常都只 是包含头文件而不会包含实现文件,所以在.m文件中声明的成员变量是@private ...
- 基于微软平台IIS/ASP.NET开发的大型网站有哪些呢?
首先说明一下,本文绝不是要说Microsoft平台多么好,多么牛.只是要提醒一些LAMP/JAVA平台下的同志们,微软平台不至于像你们说的,和想象的那么不堪!只是你们自己不知道而已.同时,也希望广大M ...
- 1、HTML学习 - IT软件人员学习系列文章
本文做为<IT软件人员学习系列文章>的第一篇,将从最基本的开始进行描述,了解的人完全可以跳过本文(后面会介绍一些工具). 今天讲讲Web开发中最基础的内容:HTML(超文本标记语言).HT ...
- [整理]PHP/HTML混写的四种方式
PHP作为一款后端语言,为了输出给浏览器让浏览器呈现出来,无可避免的要输出HTML代码,下文介绍下我用过的三种PHP/HTML混编方法 1.单/双引号包围法 这是最初级的方法了,用法就像下面这样 &l ...
- Mongodb Manual阅读笔记:CH3 数据模型(Data Models)
3数据模型(Data Models) Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mon ...