【从零开始写一个简单的ImageLoader框架】ImageLoader分析
来源:互联网 发布:mac 天猫品牌日 编辑:程序博客网 时间:2024/06/05 03:30
相关文章
【从零开始写一个简单的ImageLoader框架】项目介绍
【从零开始写一个简单的ImageLoader框架】ImageLoader分析
【从零开始写一个简单的ImageLoader框架】MyImageLoader代码简介
项目涉及知识点
1、网络获取
2、图片压缩
3、内存缓存
4、磁盘缓存
5、线程池
6、Handler
7、RecyclerView(demo中使用)
ImageLoader获取图片一般流程
1、从内存缓存中查看是否有该图片,如果有就设置到imageView上。
2、如果没有内存缓存,就从磁盘缓存中查看是否有该图片,如果有就设置到imageView上,并且把该图片设置到内存缓存中。
3、如果既没有内存缓存也没有磁盘缓存,那么就直接从网络获取该图片,并使用磁盘缓存,然后从磁盘中读取该图片。将图片根据ImageView的宽高压缩后进行显示。
4、由于获取内存缓存较快,所以不需要使用线程。
而磁盘缓存由于存在从网络下载图片这一较为耗时的环节,所以要使用线程。
考虑到可能会有多个图片同时显示,所以就要使用线程池进行统一管理。
5、在线程中无法直接更新UI,所以也要使用到Handler。
从代码了解流程(建议结合源码看)
代码预览
在笔者demo中主要使用到的方法为bindBitMap,此方法使用与ImageRecyclerAdapter中
public void setData(String url) { //垂直线性布局 //加载高清图片并按宽高压缩 //MyUtils.Log(url); MyImageLoader.getInstance(context).bindBitmap(url, imageView, width, height); }
我们直接跳转到bindBitmap中看逻辑:
public void bindBitmap(final String uri, final ImageView imageView, final int reqWidth, final int reqHeight) { //设置加载loadding图片 imageView.setImageResource(R.drawable.ic_loading); //从内存缓存中获取bitmap Bitmap bitmap = imageLrucache.loadBitmapFromMemCache(uri); if (bitmap != null) { imageView.setImageBitmap(bitmap); return; } //磁盘缓存包含在LoadBitmapTask中 LoadBitmapTask loadBitmapTask = new LoadBitmapTask(mContext, imageView, uri, reqWidth, reqHeight); //使用线程池去执行Runnable对象 THREAD_POOL_EXECUTOR.execute(loadBitmapTask); }
可以看到,如果内存缓存读到了bitmap,那么就会直接显示并且退出,如果没有,那么就会执行LoadBitmapTask,LoadBitmapTask是一个Runnable对象,使用线程池调用时,它的逻辑会是在线程中进行的,我们可以继续看一下里面的逻辑。
@Override public void run() { //从磁盘或者网络获取bitmap final Bitmap bitmap = loadBitmap(uri, reqWidth, reqHeight); //使用handler更新UI TaskResult loaderResult = new TaskResult(imageView, bitmap); imageHandler.obtainMessage(MESSAGE_POST_RESULT, loaderResult).sendToTarget(); if (callback != null) { Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { callback.onResponse(bitmap); } }); } }
我们发现loadBitmap(uri, reqWidth, reqHeight)在之后,就直接使用Handler进行UI的操作了,那么线程逻辑必然在这个里面。
private Bitmap loadBitmap(String uri, int reqWidth, int reqHeight) { Bitmap bitmap = null; try { //从磁盘缓存中获取bitmap bitmap = MyImageLoader.getImageDiskLruCache(mContext).loadBitmapFromDiskCache(uri, reqWidth, reqHeight); if (bitmap != null) { MyUtils.Log("从磁盘缓存中获取到了bitmap"); //添加到内存缓存中 MyImageLoader.getImageLruCache().put(MD5Utils.hashKeyFromUrl(uri), bitmap); return bitmap; } else { //从网络下载bitmap到磁盘缓存,并从磁盘缓存中获取bitmap bitmap = loadBitmapFromHttp(uri, reqWidth, reqHeight); if (bitmap != null) { MyUtils.Log("从网络下载并保存到磁盘并从中读取bitmap成功"); } } } catch (IOException e) { e.printStackTrace(); } if (bitmap == null && !mIsDiskLruCacheCreated) { //如果sd卡已满,无法使用磁盘缓存,则通过网络下载bitmap,一般不会调用这一步 bitmap = NetWork.downloadBitmapFromUrl(uri); MyUtils.Log("sd卡满了,直接从网络获取"); } return bitmap; }
如上,我们就找到了磁盘缓存的代码了:从磁盘缓存中如果找到了图片,就会将图片添加到内存缓存中并返回bitmap,如果没有找到,就会从网上进行下载。
知识点详述链接
以下知识点于《Android开发艺术探索》中均有阐述。
1、图片压缩
此文章来自 中文版的Android Training。
http://hukai.me/android-training-course-in-chinese/graphics/displaying-bitmaps/load-bitmap.html
2、内存缓存
此文章来自 中文版的Android Training。
http://hukai.me/android-training-course-in-chinese/graphics/displaying-bitmaps/cache-bitmap.html
3、磁盘缓存
Android DiskLruCache完全解析,硬盘缓存的最佳方案
此文章为郭霖前辈所著。
http://blog.csdn.net/guolin_blog/article/details/28863651
4、线程池
此文章来自 中文版的Android Training。
http://hukai.me/android-training-course-in-chinese/performance/multi-threads/create-threadpool.html
5、Handler
Handler类和Handler,Loop,MessageQueue的工作原理
http://blog.csdn.net/double2hao/article/details/50991441
7、RecyclerView(demo中使用)
android RecyclerView布局真的只是那么简单!(笔者原创)
http://blog.csdn.net/double2hao/article/details/51177594
项目下载地址
http://download.csdn.net/detail/double2hao/9601732
- 【从零开始写一个简单的ImageLoader框架】ImageLoader分析
- 【从零开始写一个简单的ImageLoader框架】项目介绍
- 【从零开始写一个简单的ImageLoader框架】MyImageLoader代码简介
- ImageLoader的简单分析
- ImageLoader的简单分析(二)
- ImageLoader的一个简单设置
- ImageLoader的简单分析(四)
- ImageLoader的简单分析(五)
- ImageLoader的简单分析(终结篇)
- Imageloader的简单配置
- 实现简单的ImageLoader
- ImageLoader的简单使用
- imageloader的简单使用
- ImageLoader的简单使用
- ImageLoader的简单使用
- 简单的imageloader
- Imageloader的简单实用
- ImageLoader的简单使用
- Github上Stars最多的53个深度学习项目,TensorFlow遥遥领先
- ConcurrentLinkedQueue学习(二)
- 重写数据结构--二叉树
- Caffe学习笔记7:其他常用层和参数
- CSS对话框样式
- 【从零开始写一个简单的ImageLoader框架】ImageLoader分析
- 关于Myeclipse的search工具
- const 123和static 123
- Java 实现邮件的接收
- Spark 启动脚本分析
- EtherNet/IP工业以太网协议白皮书
- c#调用C++ dll 报未将对象引用到设置对象的实例 的解决方案
- nmap的使用
- 跳舞 (Standard IO)