Android中高效的显示图片之一 ——加载大图
在网上看了不少文章,发现还是官方文档介绍最详细,把重要的东西简单摘要出来。详细可看官方文档地址 ( http://www.bangchui.org/read.php?tid=9 ) 。
在应用中显示图片,如果不多加小心,很容易就会使应用因为异常“java.lang.OutofMemoryError:bitmap size exceeds VM budget”而导致crash。在android中加载图片需要一定的技巧性,主要是因为:
1.通常设备资源有限,安卓设备给每个应用只分配16M的空间。当然很多设备都为应用设置了更高的内存,下面这个文档的3.7节中有介绍不同屏幕设备应用需要的最小内存(http://source.android.com/compatibility/downloads.html)。
2.图片通常很占内存。例如Galxy Nexus相机分辨率高达2592x1936,如果图片配置为ARGB_8888(2.3以后默认配置),加载一张照片就需要19M内存(2592x1936x4 bytes),会很快消耗完一个应用的内存。
3.安卓的UI中通常需要一下加载多张图片,如ListView,ViewPager。
本文主要介绍怎么高效地加载大图而不至于使你的应用内存溢出。大图通常会比屏幕尺寸大很多,然而加载一个高分辨率的图片并不能带来多少视觉体验,通过下面两步可以加载一个压缩尺寸的图片就节省内存。
第一步,读取图片尺寸和类型。
BitmapFactory类提供了多个decoding方法(decodeByteArray(), decodeFile(), decodeResource(), 等)使可以通过各种数据源创建Bitmap,这些方法会在bitmap构造时申请内存,对于大图,这样会很容易导致内存溢出。每种decode方法都有一个额外的标志参数BitmapFactory.Options,设置它的inJustDecodeBounds属性为true,可以避免decode时分配内存,返回的Bitmap对象是一个null值,但能得到图片的原始高度、宽度和格式(保存在option的outWidth,outHeight,outMimeType中)。通过这种方式,可以在构造图片前获得图片属性。下面是示例代码:
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
- int imageHeight = options.outHeight;
- int imageWidth = options.outWidth;
- String imageType = options.outMimeType;
为了避免内存溢出,最好在加载图片前都对尺寸做检查,除非你保证源图片没有大图。
第二步,加载缩小后的图片到内存。
现在知道了原图片的尺寸,根据实际情况决定你要加载它缩小多少倍后的图片。例如你用一个128x96的ImageView显示一张1024x768的原图,根本没有必要把原图读加载到内存。加载一张缩小后的图片到内存,只需要把BitmapFactory.Options对象的inSampleSize设为true,然后给inSampleSize设一个值就行了(可以理解inSampleSize为n,图片就缩小到1/n大小)。
下面是一段加载图片的一段示例代码
- public static int calculateInSampleSize(
- BitmapFactory.Options options, int reqWidth, int reqHeight) {
- // Raw height and width of image
- final int height = options.outHeight;
- final int width = options.outWidth;
- int inSampleSize = 1;
- if (height > reqHeight || width > reqWidth) {
- if (width > height) {
- inSampleSize = Math.round((float)height / (float)reqHeight);
- } else {
- inSampleSize = Math.round((float)width / (float)reqWidth);
- }
- }
- return inSampleSize;
- }
- public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
- int reqWidth, int reqHeight) {
- // First decode with inJustDecodeBounds=true to check dimensions
- final BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeResource(res, resId, options);
- // Calculate inSampleSize
- options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
- // Decode bitmap with inSampleSize set
- options.inJustDecodeBounds = false;
- return BitmapFactory.decodeResource(res, resId, options);
- }
Android中高效的显示图片之一 ——加载大图的更多相关文章
- Android中高效的显示图片之二——在非UI线程中处理图片
在“加载大图”文章中提到的BitmapFactory.decode*方法,如果源数据是在磁盘.网络或其它任何不是在内存中的位置,那么它都不应该在UI线程中执行.因为它的加载时间不可预测且依赖于一系列因 ...
- Android中高效的显示图片之三——缓存图片
加载一张图片到UI相对比较简单,如果一次要加载一组图片,就会变得麻烦很多.像ListView,GridView,ViewPager等控件,需要显示的图片和将要显示的图片数量可能会很大. 为了减少内存使 ...
- Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案
转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53205878本文出自[DylanAndroid的博客] Android中Vie ...
- Android中使用WebView, WebChromeClient和WebViewClient加载网页 (能够执行js)
Android中使用WebView, WebChromeClient和WebViewClient加载网页 在android应用中,有时要加载一个网页,如果能配上一个进度条就更好了,而android ...
- Android训练课程(Android Training) - 高效的显示图片
高效的显示图片(Displaying BitmapsEfficiently) 了解如何使用通用的技术来处理和读取位图对象,让您的用户界面(UI)组件是可响应的,并避免超过你的应用程序内存限制的方式.如 ...
- Android中自定义ListView实现上拉加载更多和下拉刷新
ListView是Android中一个功能强大而且很常用的控件,在很多App中都有ListView的下拉刷新数据和上拉加载更多这个功能.这里我就简单记录一下实现过程. 实现这个功能的方法不止一个,Gi ...
- Android中使用WebView, WebChromeClient和WebViewClient加载网页
在android应用中,有时要加载一个网页,如果能配上一个进度条就更好了,而android 中提供了其很好的支持, 其中webView的一系列用法,比如 webView.getSettings().s ...
- 前端性能优化成神之路--图片懒加载(lazyload image)
图片懒加载(当然不仅限于图片,还可以有视频,flash)也是一种优化前端性能的方式.使用懒加载可以想要看图片时才加载图片,而不是一次性加载所有的图片,从而在一定程度从减少服务端的请求 什么是懒加载 懒 ...
- Android新浪微博客户端(七)——ListView中的图片异步加载、缓存
原文出自:方杰|http://fangjie.info/?p=193转载请注明出处 最终效果演示:http://fangjie.sinaapp.com/?page_id=54 该项目代码已经放到git ...
随机推荐
- JVM调优- jmap(转)
http://blog.csdn.net/fenglibing/article/details/6411953 1.介绍 打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些 ...
- 设置tableView背景颜色
[treeTableView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight] ...
- hdu_吃糖果(思维题)
吃糖果 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submiss ...
- POJ 2965 The Pilots Brothers' refrigerator【枚举+dfs】
题目:http://poj.org/problem?id=2965 来源:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=26732#pro ...
- 用VirtualBox和vagrant在win7×64上搭建ruby on rails 开发环境
下载准备 1.vagrant 官方 WINDOWS Universal (32 and 64-bit) http://www.vagrantup.com/downloads.html 2.Virtu ...
- Symfony 使用KnpTimeBundle
使用time_diff时出现:diff.ago.hour; 解决:1:引入"knplabs/knp-time-bundle": "^1.7",https://g ...
- android ui篇 自己写界面
对于一些较为简单的界面则自己进行写. 在这里就需要了解xml文件中一些基本的属性以及android手机的知识. 一.目前手机屏幕像素密度基本有5种情况.(以下像素密度简称密度) 密度 ldpi mdp ...
- 33_为应用添加多个Activity与参数传递
1\ 2\ 3\ 4\ 2 3
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
- vmstat测试
vmstat测试:场景:tar -zvcf 2_104.tar.gz ./* 打包压缩3GB+文件 [root@localhost opt]# vmstat 1 1000procs --------- ...