viewpage listview gridview加载本地大图多图OOM处理办法
很少上博客园写东西了.
最近在写公司项目,由于需要加载本地相册通过viewpager方式来加载,
最后发现直接进入界面就OOM了.
经过几天的整理最终搞定.
现在将加载本地和加载网络图片的缓存工具类贴出代码.
需要用的直接调用其中的暴露出的方法,传入本地图片地址或网络图片地址 +imageview即可
代码如有问题请及时跟帖或者加QQ30338970交流.
- package cn.haodehaode.utils;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.AsyncTask;
- import android.support.v4.util.LruCache;
- import android.widget.ImageView;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.HashSet;
- import java.util.Set;
- import cn.haodehaode.R;
- /**
- * 图片缓存
- * 异步加载网络图片
- *
- * @author JALEN c9n9m@163.com
- * @version V1.0
- * @Title: ${FILE_NAME}
- * @Package cn.haodehaode.utils
- * @Description: ${todo}
- * @date 15/10/29 13:39
- */
- public class LruCacheImgUrlUtils {
- private static LruCache<String, Bitmap> mMemoryCache;
- private static LruCacheImgUrlUtils lruCacheSingleton;
- /**
- * 记录所有正在下载或等待下载的任务。
- */
- private static Set<BitmapWorkerTasks> taskCollection;
- public static synchronized LruCacheImgUrlUtils getLruUrlCacheSingleton() {
- if (lruCacheSingleton == null) {
- lruCacheSingleton = new LruCacheImgUrlUtils();
- taskCollection = new HashSet<BitmapWorkerTasks>();
- // LruCache通过构造函数传入缓存值,以KB为单位。
- int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
- // 使用最大可用内存值的1/8作为缓存的大小。
- int cacheSize = maxMemory / 8;
- mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
- @Override
- protected int sizeOf(String key, Bitmap bitmap) {
- // 重写此方法来衡量每张图片的大小,默认返回图片数量。
- return bitmap.getByteCount() / 1024;
- }
- };
- }
- return lruCacheSingleton;
- }
- /**
- * 将一张图片存储到LruCache中。
- *
- * @param key LruCache的键,这里传入图片的URL地址。
- * @param bitmap LruCache的键,这里传入从网络上下载的Bitmap对象。
- */
- public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
- if (getBitmapFromMemoryCache(key) == null) {
- mMemoryCache.put(key, bitmap);
- }
- }
- /**
- * 从LruCache中获取一张图片,如果不存在就返回null。
- *
- * @param key LruCache的键,这里传入图片的URL地址。
- * @return 对应传入键的Bitmap对象,或者null。
- */
- public Bitmap getBitmapFromMemoryCache(String key) {
- return mMemoryCache.get(key);
- }
- /**
- * 给ImageView设置图片。首先从LruCache中取出图片的缓存,设置到ImageView上。如果LruCache中没有该图片的缓存,
- * 就给ImageView设置一张默认图片。
- *
- * @param imageUrl 图片的URL地址,用于作为LruCache的键。
- * @param imageView 用于显示图片的控件。
- */
- public void setImageView(String imageUrl, ImageView imageView) {
- Bitmap bitmap = getBitmapFromMemoryCache(imageUrl);
- if (bitmap != null) {
- imageView.setImageBitmap(bitmap);
- } else {
- imageView.setImageResource(R.drawable.empty_photo);
- BitmapWorkerTasks task = new BitmapWorkerTasks(imageView);
- task.execute(imageUrl);
- }
- }
- /**
- * 异步下载图片的任务。
- *
- * @author guolin
- */
- class BitmapWorkerTasks extends AsyncTask<String, Void, Bitmap> {
- private ImageView mImageView;
- public BitmapWorkerTasks(ImageView imageView) {
- mImageView = imageView;
- }
- /**
- * 图片的URL地址
- */
- private String imageUrl;
- @Override
- protected Bitmap doInBackground(String... params) {
- imageUrl = params[0];
- // 在后台开始下载图片
- Bitmap bitmap = downloadBitmap(params[0]);
- if (bitmap != null) {
- // 图片下载完成后缓存到LrcCache中
- addBitmapToMemoryCache(params[0], bitmap);
- }
- return bitmap;
- }
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- super.onPostExecute(bitmap);
- // 根据Tag找到相应的ImageView控件,将下载好的图片显示出来。
- if (mImageView != null && bitmap != null) {
- mImageView.setImageBitmap(bitmap);
- }
- taskCollection.remove(this);
- }
- /**
- * 建立HTTP请求,并获取Bitmap对象。
- *
- * @param imageUrl 图片的URL地址
- * @return 解析后的Bitmap对象
- */
- private Bitmap downloadBitmap(String imageUrl) {
- Bitmap bitmap = null;
- HttpURLConnection con = null;
- try {
- URL url = new URL(imageUrl);
- con = (HttpURLConnection) url.openConnection();
- con.setConnectTimeout(5 * 1000);
- con.setReadTimeout(10 * 1000);
- bitmap = BitmapFactory.decodeStream(con.getInputStream());
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (con != null) {
- con.disconnect();
- }
- }
- return bitmap;
- }
- }
- }
- package cn.haodehaode.utils;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.AsyncTask;
- import android.support.v4.util.LruCache;
- import android.widget.ImageView;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.HashSet;
- import java.util.Set;
- import cn.haodehaode.R;
- /**
- * 图片缓存
- *
- * @author JALEN c9n9m@163.com
- * @version V1.0
- * @Title: ${FILE_NAME}
- * @Package cn.haodehaode.utils
- * @Description: ${todo}
- * @date 15/10/29 13:39
- */
- public class LruCacheImgUtils {
- private static LruCache<String, Bitmap> mMemoryCache;
- private static LruCacheImgUtils lruCacheSingleton;
- public static synchronized LruCacheImgUtils getLruCacheSingleton() {
- if (lruCacheSingleton == null) {
- lruCacheSingleton = new LruCacheImgUtils();
- // LruCache通过构造函数传入缓存值,以KB为单位。
- int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
- // 使用最大可用内存值的1/8作为缓存的大小。
- int cacheSize = maxMemory / 8;
- mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
- @Override
- protected int sizeOf(String key, Bitmap bitmap) {
- // 重写此方法来衡量每张图片的大小,默认返回图片数量。
- return bitmap.getByteCount() / 1024;
- }
- };
- }
- return lruCacheSingleton;
- }
- public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
- if (getBitmapFromMemCache(key) == null) {
- mMemoryCache.put(key, bitmap);
- }
- }
- public Bitmap getBitmapFromMemCache(String key) {
- return mMemoryCache.get(key);
- }
- public void loadBitmap(String path, ImageView imageView) {
- final Bitmap bitmap = getBitmapFromMemCache(path);
- if (bitmap != null) {
- imageView.setImageBitmap(bitmap);
- } else {
- imageView.setImageResource(R.drawable.default_image);
- BitmapWorkerTask task = new BitmapWorkerTask(imageView);
- task.execute(path);
- }
- }
- public Bitmap decodeSampledBitmapFromResource(String path,
- int reqWidth, int reqHeight) {
- // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
- final BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(path, options);
- // 调用上面定义的方法计算inSampleSize值
- options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
- // 使用获取到的inSampleSize值再次解析图片
- options.inJustDecodeBounds = false;
- return BitmapFactory.decodeFile(path, options);
- }
- public static int calculateInSampleSize(BitmapFactory.Options options,
- int reqWidth, int reqHeight) {
- // 源图片的高度和宽度
- final int height = options.outHeight;
- final int width = options.outWidth;
- int inSampleSize = 1;
- if (height > reqHeight || width > reqWidth) {
- // 计算出实际宽高和目标宽高的比率
- final int heightRatio = Math.round((float) height / (float) reqHeight);
- final int widthRatio = Math.round((float) width / (float) reqWidth);
- // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
- // 一定都会大于等于目标的宽和高。
- inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
- }
- return inSampleSize;
- }
- class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
- private ImageView mImageView;
- public BitmapWorkerTask(ImageView imageView) {
- mImageView = imageView;
- }
- // 在后台加载图片。
- @Override
- protected Bitmap doInBackground(String... params) {
- final Bitmap bitmap = decodeSampledBitmapFromResource(
- params[0], 320, 320);
- addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
- return bitmap;
- }
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- super.onPostExecute(bitmap);
- mImageView.setImageBitmap(bitmap);
- }
- }
- }
viewpage listview gridview加载本地大图多图OOM处理办法的更多相关文章
- 微信小程序-工具无法加载本地模拟开发服务的解决办法
微信小程序开发工具出现如下问题: 因为网络代理软件或者 VPN 影响,工具无法加载本地模拟开发服务 请尝试以下任一解决方案1.关闭相关网络代理软件,重新编译成功后,再启动相关网络代理软件: 2.配置 ...
- ListView异步加载图片,完美实现图文混排
昨天参加一个面试,面试官让当场写一个类似于新闻列表的页面,文本数据和图片都从网络上获取,想起我还没写过ListView异步加载图片并实现图文混排效果的文章,so,今天就来写一下,介绍一下经验. Lis ...
- wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)
wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...
- Android ListView只加载当前屏幕内的图片(解决list滑动时加载卡顿)
最近在做ListView分页显示,其中包括图片 和文字(先下载解析文字内容,再异步加载图片)发现每次点击下一页后,文字内容加载完毕,马上向下滑动,由于这时后台在用线程池异步下载图片,我每页有20条,也 ...
- #iOS问题记录#动态Html加载本地CSS和JS文件
所谓动态Html,指代码中组合生成的html字符串: 若需要加载本地CSS,图片,JS文件,则, 1,需要文件的全路径: 2,需要"file:///"标志: 例如: //获取文件全 ...
- AppCan学习笔记----关闭页面listview动态加载数据
AppCan页面关闭 AppCan 的页面是由两个HTML组成,如果要完全关闭的话需要在主HTML eg.index.html中关闭,关闭方法:appcan.window.close(-1); 管道 ...
- 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图
[源码下载] 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Co ...
- iOS --- UIWebView的加载本地数据的三种方式
UIWebView是IOS内置的浏览器,可以浏览网页,打开文档 html/htm pdf docx txt等格式的文件. safari浏览器就是通过UIWebView做的. 服务器将MIM ...
- UIWebView加载本地html文件
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(, , KScreenWidth, KScreenHeight-)]; ...
随机推荐
- shell循环
for循环 for循环一般格式为: for 变量 in 列表 do command1 command2 ... commandN done 列表是一组值(数字.字符串等)组成的序列,每个值通过空格分隔 ...
- coalesce函数用法
COALESCE函数会依次检查输入的参数,返回第一个不是NULL的参数,只有当传入COALESCE函数的所有的参数都是NULL的时候,函数才会返回NULL
- 用sql取出来的list需要处理成map的两种情况
1. 原生sql: select a.id,a.name from a SQLQuery sqlQuery=this.getSession().createSQLQuery(sb.toString() ...
- C++中的注解理解
SAL: the Microsoft Source Code Annotation Language. SAL: the Microsoft Source Code Annotation Langua ...
- Cannot refer to an instance field pageTitle while explicitly invoking a cons
当下面这样时在第7行会提示:Cannot refer to an instance field pageTitle while explicitly invoking a cons public cl ...
- 教你如何快速下载旧版本的Firefox浏览器
http://blog.csdn.net/gh0st007/article/details/18937421 更新后的ff使用过程中经常出现卡顿的现象,之前并没有出现,于是想找老版本的ff安装一下.发 ...
- iOS应用内跳转系统设置相关界面的方法
在iOS开发中,有时会有跳转系统设置界面的需求,例如提示用户打开蓝牙或者WIFI,提醒用户打开推送或者位置权限等.在iOS6之后,第三方应用需要跳转系统设置界面,需要在URL type中添加一个pre ...
- 黑马程序员+ADO.Net基础(中)
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net ...
- Android 客户端设计之环境考虑
我做过两三个android客户端应用的整体设计和部分的编码,这里仅仅谈一下设计方面的故事(此乃原创2015:11:02). 做客户端设计,首先要考虑应用所在的环境,包括三方面:1 要设计的apk是在一 ...
- phoenix 开发API系列 目录
phoenix 开发API系列(一)创建简单的http api phoenix 开发API系列(二)phoenix 各类 api 实现方式 phoenix 开发API系列(三)phoenix api ...