废话不多述,首先来说明下 为什么要用图片加载器 呢,就是为了避免图片重复从网络加载。也就是在第一次从网络加载之后就把图片缓存在本地,下次用的时候直接从本地查找,有的话就直接用,没有再从网络加载。

加载方式的话又有2种,一种是加载在手机内存中,另一种是缓存到SD卡中。一般Android应用的内存很有限,所以用内存缓存的话当应用重启时缓存在内存中的就会丢失,但是缓存在内存中比缓存在SD卡中读取的时候更快,而且缓存在SD卡中需要手动释放内存,不然就变成了垃圾内存。

接下来分别讲下内存缓存和SD卡缓存,先定义一个借口规定2种缓存方式都需要完成的工作,put(加入到缓存当中)和get(从缓存中获取):

public interface ImageCache {//用url来唯一标识bitmappublic void put(String url, Bitmap bitmap);public Bitmap get(String url);
}

提到接口我有想到一个小插曲。博主最近在帮实习公司做2个SDK(就是把公司的web业务做成Android SDK),在公司就我一个搞Android开发的,其他同事对Android都不是很了解,博主听到最多的赞美无非就2种:哎呀,你的界面做的真好看;你的代码写的 真好看!!!代码好看是什么鬼。。。

(一本正紧严肃脸)缓存到内存的代码:

public class MemoryCache implements ImageCache{//用来缓存的工具类对象,通过类声明可以看出这个类也是通过key-value来存储对象的private LruCache<String, Bitmap> mImageCache;public MemoryCache(){initImageCache();}private void initImageCache() {//计算当前应用可使用内存final int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);//分配作为缓存的内存大小,官方推荐为当前应用可使用内存的1/8final int cacheSize = maxMemory / 4;//初始化缓存类mImageCache = new LruCache<String, Bitmap>(cacheSize){/*sizeof()方法。这个方法默认返回的是你缓存的item数目,如果你想要自定义size的大小,直接重写这个方法,返回自定义的值即可*/@Overrideprotected int sizeOf(String key, Bitmap bitmap) {return bitmap.getRowBytes() * bitmap.getHeight() / 1024;}};}//将资源加入内存缓存@Overridepublic void put(String url, Bitmap bitmap){mImageCache.put(url, bitmap);}//从内存缓存通过url标识来获取资源@Overridepublic Bitmap get(String url){return mImageCache.get(url);}
}

缓存到SD卡的代码如下:

public class DiskCache implements ImageCache {//缓存路径static String cacheDir = "sdcard/cache/";@Overridepublic Bitmap get(String url){return BitmapFactory.decodeFile(cacheDir + url);}@Overridepublic void put(String url, Bitmap bmp){FileOutputStream fileOutputStream = null;try {fileOutputStream = new FileOutputStream(cacheDir + url);bmp.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);} catch (Exception e){e.printStackTrace();} finally {if (fileOutputStream != null){try {fileOutputStream.close();} catch (IOException e){e.printStackTrace();}}}}
}

那到底什么时候用什么缓存方式呢?
我们可以在从网络加载图片的时候同时缓存在内存和SD卡中,当需要使用图片资源的时候就先从内存查找,没有的话再从SD卡中查找,也没有就从网络加载再缓存到本地(同时缓存到内存和SD卡)。贴上代码:

public class DoubleCache implements ImageCache{MemoryCache mMemoryCache = new MemoryCache();DiskCache mDiskCache = new DiskCache();@Overridepublic Bitmap get(String url){Bitmap bitmap = mMemoryCache.get(url);if (bitmap == null){bitmap = mDiskCache.get(url);}return bitmap;}@Overridepublic void put(String url, Bitmap bmp){mMemoryCache.put(url, bmp);mDiskCache.put(url, bmp);}
}

到这里缓存部分逻辑就写的差不多了,下面看看具体实现类面代码:

public class ImageLoader {//内存缓存ImageCache mImageCache = new DoubleCache();//线程池,线程的数量为CPU数,可以同时处理多个缓存线程//Runtime.getRuntime().availableProcessors()  得到的就是CPU数ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());public void displayImage(final String url, final ImageView imageView){Bitmap bitmap = mImageCache.get(url) ;if (bitmap != null){imageView.setImageBitmap(bitmap);return;}//图片还未缓存,开启线程从网上下载submitLoadRequest(url, imageView);}private void submitLoadRequest(final String imageUrl,final ImageView imageView){//需要开启新线程,用url唯一标识imageViewimageView.setTag(imageUrl);mExecutorService.submit(new Runnable() {@Overridepublic void run() {Bitmap bitmap = downloadImage(imageUrl);if (bitmap == null){return;}if (imageView.getTag().equals(imageUrl)){imageView.setImageBitmap(bitmap);}mImageCache.put(imageUrl, bitmap);}});}private Bitmap downloadImage(String imageUrl) {Bitmap bitmap = null;try {URL url = new URL(imageUrl);final HttpURLConnection conn = (HttpURLConnection) url.openConnection();bitmap = BitmapFactory.decodeStream(conn.getInputStream());conn.disconnect();} catch (Exception e){e.printStackTrace();}return bitmap;}
}

到这里这个简单的ImageLoader类就写好了。这就是一个很简单实用的工具类,网上比较完善的ImageLoader多得是,我写这篇博客主要是整理一下思路也是分享一下自己的学习成果。当然作为一个学生,我写的文章肯定存在一些问题或者思考欠缺的地方,也希望大家能指出我的错误或不足,反正我也不一定看得到。

Android自定义简单的图片加载器(ImageLoader)相关推荐

  1. Android中用URL模拟一个简单的图片加载器

    首先,需要添加权限. <uses-permission android:name="android.permission.INTERNET"/> 整体代码如下: pac ...

  2. PyTorch基础-自定义数据集和数据加载器(2)

    处理数据样本的代码可能会变得混乱且难以维护: 理想情况下,我们想要数据集代码与模型训练代码解耦,以获得更好的可读性和模块化.PyTorch 域库提供了许多预加载的数据(例如 FashionMNIST) ...

  3. Android 中LayoutInflater(布局加载器)之介绍篇

    本文出自博客Vander丶CSDN博客,如需转载请标明出处,尊重原创谢谢 博客地址:http://blog.csdn.net/l540675759/article/details/78099358 前 ...

  4. Universal-Image-Loader解析(二)——DisplayImageOptions的详细配置与简单的图片加载...

    在使用这个框架的时候,我们必须要配置一个DisplayImageOptions对象来作为ImageLoader.getInstance().displayImage()中的参数,所以很有必要讲解这个对 ...

  5. DisplayImageOptions的详细配置与简单的图片加载

    在使用这个框架的时候,我们必须要配置一个DisplayImageOptions对象来作为ImageLoader.getInstance().displayImage()中的参数,所以很有必要讲解这个对 ...

  6. Carson带你学Android:主流开源图片加载库对比(UIL、Picasso、Glide、Fresco)

    前言 图片加载在 Android开发项目中十分常见 为了降低开发周期 & 难度,我们经常会选用一些图片加载的开源库,而现在图片加载开源库越来越多,我们应该选用哪种呢? 今天.我就给大家介绍 & ...

  7. OkGo第三方框架的上传与下载+Glide图片加载器

    OkGo第三方框架 OkGo依赖:implementation 'com.lzy.net:okgo:3.0.4' OkGo下载文件 OkGo.<File>get("http:// ...

  8. Android自助餐之大图片加载

    Android自助餐之大图片加载 原理 使用BitmapFactory.decodeStreeam()方法,该方法会调用native层代码来创建bitmap(两个重载都会调用) 使用带BitmapFa ...

  9. Android中常见的图片加载框架

    图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行 ...

最新文章

  1. 为何python攀上数据科学巅峰?调查显示Python超越R
  2. 计算机和单片机概述,微机与单片机概述课件.ppt
  3. Zookeeper的一致性协议:Zab
  4. 为什么薄膜干涉的厚度要很小_薄膜干涉的膜为什么不能太厚?
  5. RabbitMQ发布/订阅模式(Publish/Subscribe)
  6. java通信方式_java 认知底层的五种通信方式
  7. 销毁Session和清空指定的属性
  8. rubyinstaller2 32/64位 2.3.3
  9. poi完成word、excel、pdf添加斜体水印
  10. 句子反转:小米笔试编程题目——python
  11. 家用千兆路由器排行榜前十名_公认最好的路由器牌子
  12. python yield是什么意思_python yield有什么用
  13. 大鱼吃小鱼c语言编程,scratch大鱼吃小鱼设计思路
  14. mysql 临时表 会话级_会话级的临时表和事务级的临时表
  15. 科比坠机事故调查报告出炉,历史上那些神秘的空难原来都因为这个!
  16. python签到脚本_基于Python实现签到脚本过程解析
  17. 苹果iPad怎么录屏?简单易懂,1分钟学会
  18. IDEA部署项目到tomcat运行成功但是页面404的两种原因
  19. JMeter接口自动化发包与示例
  20. Pohlig-Hellman算法解决DLP问题

热门文章

  1. java中tomcat_Java中Tomcat各版本比较
  2. Verilog中if- else if语句和case语句用法:
  3. vue 和 uniapp 的密码框小眼睛(通用)
  4. 浅谈RPG游戏中的属性系统设定
  5. 《Nacos(2) - 服务发现》
  6. .NET Core中NETSDK1061错误解决(转载)
  7. 「PAT乙级真题解析」Basic Level 1100 校庆 (问题分析+完整步骤+伪代码描述+提交通过代码)
  8. EOS的CPU危机:BM的租赁模式或只是乌托邦
  9. 机器人学中的状态估计——学习笔记
  10. 互联网大厂2021中秋礼盒pk,看完我又酸了……