自己设计实现图片加载器

这里不贴大段的代码了,单单列出思路,和一些解决思路。

我们的图片加载过程,可以引入缓存,我们设计一种两层缓存的架构,当拿到一个需要加载的图片的url时,我们先从内存缓存中根据url查找看内存缓存有没有相关缓存,如果没有,那么我们在磁盘缓存中进行查找,如果磁盘缓存也没有,那么我们需要发出真正的网络请求,进行图片的加载,当图片网络加载成功时将图片存入两级缓存。
内存缓存的实现,可以借助LruCache,大小可以指定为app可用内存的8分之一。
磁盘缓存可以借助DiskLruCache,也可以自己在app的缓存目录下进行文件io,注意由于文件Io比较慢,因此存和取最好都要开启新的异步任务。另外如果自己进行实现,可以考虑对url进行MD5运算,将文件名取为hash值,同时使用app缓存文件时,最好自己在建一个子目录。另外app内部可以有一个菜单展示当前磁盘缓存大小,方便进行清理。
网络请求的实现,最基本的要通过异步任务来获取图片。

加载图片的优化问题。
图片是各式各样的,大多数情况下,我们要展示的图片,比原始图片小很多。比如用户头像控件只有6464,如果用户的头像的原始文件有512512,那么即使我们加载了原始图片,然而肉眼也看不出区别。因此,我们加载图片的时候,可以先获取即将加载的图片的大小,格式等,然后根据需要的尺寸,加载重新采样的版本。这一个过程,对于网络加载同样适用。BitmapFactory的decodeStream可以从网络输入流加载图片。不过如果我们先测量,后加载,可能会爆io异常,这是由于同一个输入流被读取了两次。根据api,第一次测量的时候,输入流的读取位置被改变了,如果需要再次读取,需要先复位。然而我测试发现,即使复位,也有可能报异常,因此参考了网络的其它回答。我们可以将输入流数据写入字节数组输出流中,然后就可以多次对流进行操作了。

网络请求的发出优化
当需要加载大量图片时,可能会有这样的场景,即当前页面的图片还没有加载出来,我们已经滑动到了其它页面,或者下一页,这导致发出的网络请求越来越多,而用户目前正在查看的内容的网络请求无法最快完成。比如在一个展示图片的app中,上拉会加载更多图片。如果在当前页的图片未完全展示的情况下,用户进行了多次上拉操作,那么即使一开始的页面的图片已经没用了,后台的网络请求还是回去先加载它们,从而使得当前用户停留页面的图片得不到即使加载。
我在实现中曾引入一个简单的设计,一个存储异步任务的数组,发出任务时,加入数组,如果超过一定的阈值,那么就取消最先加入的任务,而添加新的任务。

你可能感兴趣的:(自己设计实现图片加载器)