很少上博客园写东西了.

最近在写公司项目,由于需要加载本地相册通过viewpager方式来加载,

最后发现直接进入界面就OOM了.

经过几天的整理最终搞定.

现在将加载本地和加载网络图片的缓存工具类贴出代码.

需要用的直接调用其中的暴露出的方法,传入本地图片地址或网络图片地址 +imageview即可

代码如有问题请及时跟帖或者加QQ30338970交流.

  1. package cn.haodehaode.utils;
  2.  
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.os.AsyncTask;
  6. import android.support.v4.util.LruCache;
  7. import android.widget.ImageView;
  8.  
  9. import java.net.HttpURLConnection;
  10. import java.net.URL;
  11. import java.util.HashSet;
  12. import java.util.Set;
  13.  
  14. import cn.haodehaode.R;
  15.  
  16. /**
  17. * 图片缓存
  18. * 异步加载网络图片
  19. *
  20. * @author JALEN c9n9m@163.com
  21. * @version V1.0
  22. * @Title: ${FILE_NAME}
  23. * @Package cn.haodehaode.utils
  24. * @Description: ${todo}
  25. * @date 15/10/29 13:39
  26. */
  27. public class LruCacheImgUrlUtils {
  28.  
  29. private static LruCache<String, Bitmap> mMemoryCache;
  30.  
  31. private static LruCacheImgUrlUtils lruCacheSingleton;
  32.  
  33. /**
  34. * 记录所有正在下载或等待下载的任务。
  35. */
  36. private static Set<BitmapWorkerTasks> taskCollection;
  37.  
  38. public static synchronized LruCacheImgUrlUtils getLruUrlCacheSingleton() {
  39. if (lruCacheSingleton == null) {
  40. lruCacheSingleton = new LruCacheImgUrlUtils();
  41.  
  42. taskCollection = new HashSet<BitmapWorkerTasks>();
  43. // LruCache通过构造函数传入缓存值,以KB为单位。
  44. int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
  45. // 使用最大可用内存值的1/8作为缓存的大小。
  46. int cacheSize = maxMemory / 8;
  47. mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
  48. @Override
  49. protected int sizeOf(String key, Bitmap bitmap) {
  50. // 重写此方法来衡量每张图片的大小,默认返回图片数量。
  51. return bitmap.getByteCount() / 1024;
  52. }
  53. };
  54. }
  55. return lruCacheSingleton;
  56. }
  57.  
  58. /**
  59. * 将一张图片存储到LruCache中。
  60. *
  61. * @param key LruCache的键,这里传入图片的URL地址。
  62. * @param bitmap LruCache的键,这里传入从网络上下载的Bitmap对象。
  63. */
  64. public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
  65. if (getBitmapFromMemoryCache(key) == null) {
  66. mMemoryCache.put(key, bitmap);
  67. }
  68. }
  69.  
  70. /**
  71. * 从LruCache中获取一张图片,如果不存在就返回null。
  72. *
  73. * @param key LruCache的键,这里传入图片的URL地址。
  74. * @return 对应传入键的Bitmap对象,或者null。
  75. */
  76. public Bitmap getBitmapFromMemoryCache(String key) {
  77. return mMemoryCache.get(key);
  78. }
  79.  
  80. /**
  81. * 给ImageView设置图片。首先从LruCache中取出图片的缓存,设置到ImageView上。如果LruCache中没有该图片的缓存,
  82. * 就给ImageView设置一张默认图片。
  83. *
  84. * @param imageUrl 图片的URL地址,用于作为LruCache的键。
  85. * @param imageView 用于显示图片的控件。
  86. */
  87. public void setImageView(String imageUrl, ImageView imageView) {
  88. Bitmap bitmap = getBitmapFromMemoryCache(imageUrl);
  89. if (bitmap != null) {
  90. imageView.setImageBitmap(bitmap);
  91. } else {
  92. imageView.setImageResource(R.drawable.empty_photo);
  93. BitmapWorkerTasks task = new BitmapWorkerTasks(imageView);
  94. task.execute(imageUrl);
  95. }
  96. }
  97.  
  98. /**
  99. * 异步下载图片的任务。
  100. *
  101. * @author guolin
  102. */
  103. class BitmapWorkerTasks extends AsyncTask<String, Void, Bitmap> {
  104.  
  105. private ImageView mImageView;
  106.  
  107. public BitmapWorkerTasks(ImageView imageView) {
  108. mImageView = imageView;
  109. }
  110.  
  111. /**
  112. * 图片的URL地址
  113. */
  114. private String imageUrl;
  115.  
  116. @Override
  117. protected Bitmap doInBackground(String... params) {
  118. imageUrl = params[0];
  119. // 在后台开始下载图片
  120. Bitmap bitmap = downloadBitmap(params[0]);
  121. if (bitmap != null) {
  122. // 图片下载完成后缓存到LrcCache中
  123. addBitmapToMemoryCache(params[0], bitmap);
  124. }
  125. return bitmap;
  126. }
  127.  
  128. @Override
  129. protected void onPostExecute(Bitmap bitmap) {
  130. super.onPostExecute(bitmap);
  131. // 根据Tag找到相应的ImageView控件,将下载好的图片显示出来。
  132. if (mImageView != null && bitmap != null) {
  133. mImageView.setImageBitmap(bitmap);
  134. }
  135. taskCollection.remove(this);
  136. }
  137.  
  138. /**
  139. * 建立HTTP请求,并获取Bitmap对象。
  140. *
  141. * @param imageUrl 图片的URL地址
  142. * @return 解析后的Bitmap对象
  143. */
  144. private Bitmap downloadBitmap(String imageUrl) {
  145. Bitmap bitmap = null;
  146. HttpURLConnection con = null;
  147. try {
  148. URL url = new URL(imageUrl);
  149. con = (HttpURLConnection) url.openConnection();
  150. con.setConnectTimeout(5 * 1000);
  151. con.setReadTimeout(10 * 1000);
  152. bitmap = BitmapFactory.decodeStream(con.getInputStream());
  153. } catch (Exception e) {
  154. e.printStackTrace();
  155. } finally {
  156. if (con != null) {
  157. con.disconnect();
  158. }
  159. }
  160. return bitmap;
  161. }
  162.  
  163. }
  164.  
  165. }
  1. package cn.haodehaode.utils;
  2.  
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.os.AsyncTask;
  6. import android.support.v4.util.LruCache;
  7. import android.widget.ImageView;
  8.  
  9. import java.net.HttpURLConnection;
  10. import java.net.URL;
  11. import java.util.HashSet;
  12. import java.util.Set;
  13.  
  14. import cn.haodehaode.R;
  15.  
  16. /**
  17. * 图片缓存
  18. *
  19. * @author JALEN c9n9m@163.com
  20. * @version V1.0
  21. * @Title: ${FILE_NAME}
  22. * @Package cn.haodehaode.utils
  23. * @Description: ${todo}
  24. * @date 15/10/29 13:39
  25. */
  26. public class LruCacheImgUtils {
  27.  
  28. private static LruCache<String, Bitmap> mMemoryCache;
  29.  
  30. private static LruCacheImgUtils lruCacheSingleton;
  31.  
  32. public static synchronized LruCacheImgUtils getLruCacheSingleton() {
  33. if (lruCacheSingleton == null) {
  34. lruCacheSingleton = new LruCacheImgUtils();
  35.  
  36. // LruCache通过构造函数传入缓存值,以KB为单位。
  37. int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
  38. // 使用最大可用内存值的1/8作为缓存的大小。
  39. int cacheSize = maxMemory / 8;
  40. mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
  41. @Override
  42. protected int sizeOf(String key, Bitmap bitmap) {
  43. // 重写此方法来衡量每张图片的大小,默认返回图片数量。
  44. return bitmap.getByteCount() / 1024;
  45. }
  46. };
  47. }
  48. return lruCacheSingleton;
  49. }
  50.  
  51. public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
  52. if (getBitmapFromMemCache(key) == null) {
  53. mMemoryCache.put(key, bitmap);
  54. }
  55. }
  56.  
  57. public Bitmap getBitmapFromMemCache(String key) {
  58. return mMemoryCache.get(key);
  59. }
  60.  
  61. public void loadBitmap(String path, ImageView imageView) {
  62. final Bitmap bitmap = getBitmapFromMemCache(path);
  63. if (bitmap != null) {
  64. imageView.setImageBitmap(bitmap);
  65. } else {
  66. imageView.setImageResource(R.drawable.default_image);
  67. BitmapWorkerTask task = new BitmapWorkerTask(imageView);
  68. task.execute(path);
  69. }
  70. }
  71.  
  72. public Bitmap decodeSampledBitmapFromResource(String path,
  73. int reqWidth, int reqHeight) {
  74. // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
  75. final BitmapFactory.Options options = new BitmapFactory.Options();
  76. options.inJustDecodeBounds = true;
  77. BitmapFactory.decodeFile(path, options);
  78. // 调用上面定义的方法计算inSampleSize值
  79. options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
  80. // 使用获取到的inSampleSize值再次解析图片
  81. options.inJustDecodeBounds = false;
  82. return BitmapFactory.decodeFile(path, options);
  83. }
  84.  
  85. public static int calculateInSampleSize(BitmapFactory.Options options,
  86. int reqWidth, int reqHeight) {
  87. // 源图片的高度和宽度
  88. final int height = options.outHeight;
  89. final int width = options.outWidth;
  90. int inSampleSize = 1;
  91. if (height > reqHeight || width > reqWidth) {
  92. // 计算出实际宽高和目标宽高的比率
  93. final int heightRatio = Math.round((float) height / (float) reqHeight);
  94. final int widthRatio = Math.round((float) width / (float) reqWidth);
  95. // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
  96. // 一定都会大于等于目标的宽和高。
  97. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
  98. }
  99. return inSampleSize;
  100. }
  101.  
  102. class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
  103.  
  104. private ImageView mImageView;
  105.  
  106. public BitmapWorkerTask(ImageView imageView) {
  107. mImageView = imageView;
  108. }
  109.  
  110. // 在后台加载图片。
  111. @Override
  112. protected Bitmap doInBackground(String... params) {
  113. final Bitmap bitmap = decodeSampledBitmapFromResource(
  114. params[0], 320, 320);
  115. addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
  116. return bitmap;
  117. }
  118.  
  119. @Override
  120. protected void onPostExecute(Bitmap bitmap) {
  121. super.onPostExecute(bitmap);
  122. mImageView.setImageBitmap(bitmap);
  123. }
  124. }
  125. }

viewpage listview gridview加载本地大图多图OOM处理办法的更多相关文章

  1. 微信小程序-工具无法加载本地模拟开发服务的解决办法

    微信小程序开发工具出现如下问题: 因为网络代理软件或者 VPN 影响,工具无法加载本地模拟开发服务  请尝试以下任一解决方案1.关闭相关网络代理软件,重新编译成功后,再启动相关网络代理软件: 2.配置 ...

  2. ListView异步加载图片,完美实现图文混排

    昨天参加一个面试,面试官让当场写一个类似于新闻列表的页面,文本数据和图片都从网络上获取,想起我还没写过ListView异步加载图片并实现图文混排效果的文章,so,今天就来写一下,介绍一下经验. Lis ...

  3. wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)

    wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...

  4. Android ListView只加载当前屏幕内的图片(解决list滑动时加载卡顿)

    最近在做ListView分页显示,其中包括图片 和文字(先下载解析文字内容,再异步加载图片)发现每次点击下一页后,文字内容加载完毕,马上向下滑动,由于这时后台在用线程池异步下载图片,我每页有20条,也 ...

  5. #iOS问题记录#动态Html加载本地CSS和JS文件

    所谓动态Html,指代码中组合生成的html字符串: 若需要加载本地CSS,图片,JS文件,则, 1,需要文件的全路径: 2,需要"file:///"标志: 例如: //获取文件全 ...

  6. AppCan学习笔记----关闭页面listview动态加载数据

    AppCan页面关闭 AppCan 的页面是由两个HTML组成,如果要完全关闭的话需要在主HTML eg.index.html中关闭,关闭方法:appcan.window.close(-1); 管道 ...

  7. 重新想象 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 ...

  8. iOS --- UIWebView的加载本地数据的三种方式

    UIWebView是IOS内置的浏览器,可以浏览网页,打开文档  html/htm  pdf   docx  txt等格式的文件.  safari浏览器就是通过UIWebView做的. 服务器将MIM ...

  9. UIWebView加载本地html文件

    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(, , KScreenWidth, KScreenHeight-)]; ...

随机推荐

  1. shell循环

    for循环 for循环一般格式为: for 变量 in 列表 do command1 command2 ... commandN done 列表是一组值(数字.字符串等)组成的序列,每个值通过空格分隔 ...

  2. coalesce函数用法

    COALESCE函数会依次检查输入的参数,返回第一个不是NULL的参数,只有当传入COALESCE函数的所有的参数都是NULL的时候,函数才会返回NULL

  3. 用sql取出来的list需要处理成map的两种情况

    1. 原生sql: select a.id,a.name from a SQLQuery sqlQuery=this.getSession().createSQLQuery(sb.toString() ...

  4. C++中的注解理解

    SAL: the Microsoft Source Code Annotation Language. SAL: the Microsoft Source Code Annotation Langua ...

  5. 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 ...

  6. 教你如何快速下载旧版本的Firefox浏览器

    http://blog.csdn.net/gh0st007/article/details/18937421 更新后的ff使用过程中经常出现卡顿的现象,之前并没有出现,于是想找老版本的ff安装一下.发 ...

  7. iOS应用内跳转系统设置相关界面的方法

    在iOS开发中,有时会有跳转系统设置界面的需求,例如提示用户打开蓝牙或者WIFI,提醒用户打开推送或者位置权限等.在iOS6之后,第三方应用需要跳转系统设置界面,需要在URL type中添加一个pre ...

  8. 黑马程序员+ADO.Net基础(中)

    ---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net ...

  9. Android 客户端设计之环境考虑

    我做过两三个android客户端应用的整体设计和部分的编码,这里仅仅谈一下设计方面的故事(此乃原创2015:11:02). 做客户端设计,首先要考虑应用所在的环境,包括三方面:1 要设计的apk是在一 ...

  10. phoenix 开发API系列 目录

    phoenix 开发API系列(一)创建简单的http api phoenix 开发API系列(二)phoenix 各类 api 实现方式 phoenix 开发API系列(三)phoenix api ...