开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]

时间:2022-09-24 18:34:53

转载本专栏每一篇博客请注明转载出处地址,尊重原创。此博客转载链接地址:小杨的博客    http://blog.csdn.net/qq_32059827/article/details/52788491

上一篇对Volley做了一个初步的介绍,除了ImaggeRequest稍微有点绕之外,其它的功能跟xuils基本大同小异。再强调ImaggeRequest中的宽高参数maxWidth,maxHeight

在不是[0,0]时候会对图片做缩放。尤其是加载大图片的时候,这个工具很好用。

本篇在此基础上再介绍几个工具。其中会加入缓存的方式,以及最常用的Lruchche方式。

1、NetWorkImageView的使用

/**
* NetworkImageView的使用
*/
private void initNetworkImageView() {
mNiv.setDefaultImageResId(R.drawable.ic_launcher);//设置默认图片
mNiv.setErrorImageResId(R.drawable.tomcat);//设置错误的图片
String url = "http://192.168.1.100:8080/meinv.jpg";
RequestQueue queue = Volley.newRequestQueue(this);
ImageCache imageCache = null;
ImageLoader imageLoader= new ImageLoader(queue, imageCache);
mNiv.setImageUrl(url, imageLoader);
}

通过setImageUrl方法,传入一个urll和一个ImageLoader,即可完成url地址的图片加载。其中ImageLoader接收两个参数:1、请求队列,跟上一篇那些请求队列一样,2:自定义缓存。

我们把主要目标放在ImageCache中。这里不可以写null,写null会报错的,接下来会介绍该怎么去写。

首先,点击进入源码:

 public interface ImageCache {
public Bitmap getBitmap(String url);//获取图片
public void putBitmap(String url, Bitmap bitmap);//存图片
}

它是一个接口,因此我们肯定传入一个接口的实现类对象。而且这个接口没有任何的实现类,从而想到,volley并没有给我们提供缓存,仅仅使我们一个规范:它是必须需要我们自己去实现该接口,也就是自定义缓存。

先看看什么是内存缓存:

内存缓存

  • 1.内存缓存的核心:
    • 存:就有很多的考虑
    • 取:只需要知道唯一的key就可以了
  • 2.选择什么样的存储结构/容器/集合?Map<String,Bitmap>
  • 3.4种引用级别什么意思?
    • 强引用:我们平时使用的集合(arraylist,hashmap,hashset),即使内存oom,也不会去回收对象;
    • 软应用:使用SoftRefrence去包装一个对象,内存不足的时候去回收对象,尽量保证不oom
    • 弱应用:基本没有用过
    • 虚引用:形同虚设,同样没有用过
  • 4.删除策略/算法,我们定义的存储结构,不能继续缓存图片的时候.需要进行清理
    • LRU:最近最少使用,Least Recently Used,其实就是按照访问顺序排序
    • 删除使用次数最少的:
    • 删除占用体积最大:
  • 5. 在很久之前(2,3年)前做图片的缓存基本都是使用软应用,但是在2.3之后.google文档明确指出了软应用做缓存的一些不足.建议我们使用LruCache.class;
  • 6.举例说明删除策略的使用场景
    • LRU:电影海报图删除策略-->和时间有关系(时效性)
    • 删除使用次数最少的:-->和时间没有关系而且大小差不多
    • 删除占用体积最大:空间比较宝贵的情况

这里使用三张图片理解删除策略:

1、LRU:加载电影海报图。假设到四月份的时候,内存的海报图已经满了,那么五月份的时候海报就无法存入内存。那么就要把图片缓存在内存中去掉。我们看到:即使一月份卖的好,在四月份并没有多少人去看。最近使用最少,我就删除一月份。这就是LRU策略。

开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]

2、删除使用次数最少:下面这种情况,显然再加入图片放不进去,会报OOM。这时候这个策略就派上用场,假设右下角仅仅使用过一次,其他的都使用了上百次。那么我就有限删除右下角哪张图片,再去缓存新的图片。这就是删除使用次数最少

开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]

3、删除占用体积最大:内存已满,哪个5M的占用空间最大,我如果想加入新的图片,就把最大那张图片删掉。这就是删除占用体积最大。

开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]

再回到Lrucache:

LruCache的使用:

一个工具方法,提供了基于Lru缓存策略强引用的内存缓存,存储结构使用的LinkedHashmap

  • LinkedHashmap使用

    • LinkedHashmap和Hashmap区别:在构造方法里面多了3个参数
    • 3个参数的意义:
      • initialCapacity:初始化容器大小 例如16
      • loadFactor:负载因子(当容器占用了75%的时候76*75% = 12,就增加空间)
      • accessOrder:
        • true:LinkedHash内部会排序-->按照访问顺序排序-->这个也是为什么LruCache使用LinkedHashmap做存储结构的原因
        • false:按照插入顺序去排序
  • LruCache在什么地方可以找到?

    • 在高版本的sdk里面有.
    • 在v4包中有提供.
  • LruCache的使用
    1. 告知缓存的具体大小
    2. 覆写sizeOf方法,具体大小需要和我们定义的maxsize单位统一

LruCache底层是LinkedHashmap。我们还是进入源码稍作了解:

public class LruCache<K, V> {
private final LinkedHashMap<K, V> map;

跟踪map对象,看他是如何实例化的:

this.map = new LinkedHashMap<K, V>(0, 0.75f, true);

这三个参数,上边已经总结过了:重点要看第三个参数,再用一张图片描述一下:(设置为true后)

开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]

  1. 其中用到的数据对象是LinkedHashMap,所以不要把这个类想的多么深不可测,还是数据结构 + 算法。既然用到了这个map,自然就要有添加修改和删除操作了,用到了最近最少使用算法,自然就要用到优先级了。
  2. 作为缓存,肯定有一个缓存的大小,这个大小是可以设定的(自定义sizeOf())。当你访问了一个item(需要缓存的对象),这个item应该被加入到内存中,然后移动到一个队列的顶部,如此循环后这个队列的顶部应该是最近访问的item了,而队尾部就是很久没有访问的item,这样我们就应该对队尾部的item优先进行回收操作。
  3. 因为用到了HashMap,那么就有这个数据存储对象的特点(KEY-VALUE),放入这个map的item应该会被强引用,要回收这个对象的时候是让这个key为空,这样就让有向图找不到对应的value,最终被GC。
  4. 缓存的最大特点是不做重复的劳动,如果你之前已经缓存过这个item了,当你再次想要缓存这个item时,应该会先判断是否已经缓存好了,如果已经缓存,那么就不执行添加的操作。
  5. 我们应该能通过某个方法来清空缓存,这个缓存在app被退出后就自动清理,不会常驻内存。
  6. sizeof()方法。这个方法默认返回的是你缓存的item数目,如果你想要自定义size的大小,直接重写这个方法,返回自定义的值即可

初始化LruCache:

定义cache大小

初始化这个cache前需要设定这个cache的大小,这里的大小官方推荐是用当前app可用内存的八分之一,当然你可以视情况而定。我这里定义大小为5*1024*1024   byte大小

初始化类新建类名MyImageCache

/* 内存缓存 */
private LruCache<String, Bitmap> mMemoryCache;

设定缓存时要设定泛型,针对的是hashMap,你可以当作是key-value。我这里缓存的是bitmap,用到的key是string对象。

    LruCache<String, Bitmap> lruCache;
        //构造放方法,初始化
          public MyImageCache(){
            
              int memoryCacheSize = 5*1024 * 1024 ;//分配内存为多大
    
                 //覆写sizeOf方法
              lruCache = new LruCache<String, Bitmap>(memoryCacheSize) {
                @Override
                protected int sizeOf(String key, Bitmap bitmap) {
                    // 重写此方法来衡量每张图片的大小//这个单位要和size的单位一样都应该是byte
                    return bitmap.getByteCount();//byte单位,与上边一致
                }
            }; // 初始化LruCache对象
    }

通过缓存的值来初始化了cache对象,然后重写了sizeOf()方法。

添加/删除缓存

当我们初始化缓存后我们就应该能给这个缓存添加对象和移除对象。

    @Override
    public Bitmap getBitmap(String url) {// 取图片
        // TODO Auto-generated method stub
        return lruCache.get(url);
    }     @Override
    public void putBitmap(String url, Bitmap bitmap) {// 存图片
        // TODO Auto-generated method stub
        lruCache.put(url, bitmap);
    }

PS:对于Lrucache的案例,会在安卓简易实战教程里面给出案例。

然后再回到开始介绍的NetworkImageView代码位置,把这个自定义缓存对象传入:

/**
* NetworkImageView的使用
*/
private void initNetworkImageView() {
findViewById(R.id.btn4).setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub mNiv.setDefaultImageResId(R.drawable.ic_launcher);//设置默认图片
mNiv.setErrorImageResId(R.drawable.tomcat);//设置错误的图片
String url = "http://192.168.1.100:8080/meinv.jpg";
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
ImageCache imageCache = new MyImageCache();
ImageLoader imageLoader= new ImageLoader(queue, imageCache);
mNiv.setImageUrl(url, imageLoader);
}
});
}

这样,点击按钮会加载一张url下边的图片。到此,NetworkImageView算是讲完了。

2、ImageLoader的使用:

紧跟脚步,就是NetworkImageView的使用,因为已经介绍完了larucache,这里就特别的简单了。直接上代码就好了。如下:

/**
* imageloader的使用
*/
private void initImageLoader() {
findViewById(R.id.btn5).setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
ImageCache imageCache = new MyImageCache();
ImageLoader imageLoader = new ImageLoader(queue, imageCache);
String requestUrl = "http://192.168.1.100:8080/meinv.jpg";
imageLoader.get(requestUrl, new ImageListener() { @Override
public void onErrorResponse(VolleyError error) {
System.out.println("error:"+error.getMessage());
} @Override
public void onResponse(ImageContainer response, boolean isImmediate) {
Bitmap bitmap = response.getBitmap();
iv.setImageBitmap(bitmap);
}
},200,100);//表示有缩放。0,0无缩放
}
});
}

开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]的更多相关文章

  1. 开源框架Volley的使用《一》

    转载本专栏每一篇博客请注明转载出处地址,尊重原创.此博客转载链接地址:小杨的博客 http://blog.csdn.net/qq_32059827/article/details/52785378 本 ...

  2. 【安卓网络请求开源框架Volley源码解析系列】定制自己的Request请求及Volley框架源码剖析

    通过前面的学习我们已经掌握了Volley的基本用法,没看过的建议大家先去阅读我的博文[安卓网络请求开源框架Volley源码解析系列]初识Volley及其基本用法.如StringRequest用来请求一 ...

  3. 【安卓网络请求开源框架Volley源码解析系列】初识Volley及其基本用法

    在安卓中当涉及到网络请求时,我们通常使用的是HttpUrlConnection与HttpClient这两个类,网络请求一般是比较耗时,因此我们通常会在一个线程中来使用,但是在线程中使用这两个类时就要考 ...

  4. Android开源框架——Volley

    Volley 是 Google 在 2013 I/O 大会上推出的 Android 异步网络请求框架和图片加载框架.特别适合数据量小,通信频繁的网络操作.Volley 主要是通过两种 Diapatch ...

  5. 利用开源框架Volley来下载文本和图片。

    Android Volley是Android平台上很好用的第三方开源网络通信框架.使用简单,功能强大. 下载连接地址:http://download.csdn.net/detail/zhangphil ...

  6. Android开源框架Volley&lpar;Google IO 2013&rpar;源代码及内部实现分析

    1.Volley概述 在项目开发过 程中,博主曾写过大量的访问网络重复代码,特别是ListView adapter很难避免getView()方法不被重复调用,如果ImageView不利用缓存机制,那么 ...

  7. &lbrack;Android&rsqb; 开源框架 Volley 自定义 Request

    今天在看Volley demo (https://github.com/smanikandan14/Volley-demo), 发现自定义GsonRequest那块代码不全, 在这里贴一个全的. pu ...

  8. android网络开源框架volley&lpar;五岁以下儿童&rpar;——volley一些细节

    最近的一次volley整理出下一个.我以前没有再次遭遇了一些小问题,在该记录: 1.HttpUrlConnection DELETE 信息不能加入body问题:java.net.ProtocolExc ...

  9. NancyFx 2&period;0的开源框架的使用-Stateless&lpar;二&rpar;

    继续上一篇Stateless的博文,在上一篇的博文的基础上稍微加点东西 接下来右键解决方案添加新项目,一样建一个空的Web项目 然后在StatelessDemoWeb项目里面添加Views文件夹,Sc ...

随机推荐

  1. UVA 10090 Marbles 扩展欧几里得

    来源:http://www.cnblogs.com/zxhl/p/5106678.html 大致题意:给你n个球,给你两种盒子.第一种盒子每个盒子c1美元,可以恰好装n1个球:第二种盒子每个盒子c2元 ...

  2. Java的LockSupport&period;park&lpar;&rpar;实现分析

    LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了主要的线程同步原语.LockSupport实际上是调用了Unsafe类里的函数,归结到Unsafe里,仅仅有两个函数: ...

  3. 第七十八节,CSS3文本效果

    CSS3文本效果 一.文本阴影 CSS3提供了text-shadow文本阴影效果,这个属性在之前讲过,只是没有涉及浏览器 支持情况. 浏览器支持情况 text-shadow       Opera   ...

  4. 文件访问权限:更改用户ID

    本文来探讨一下通过更改用户ID来获取合适的文件访问权限.由于更改组ID的规则与用户ID相同,我们在这里只探讨用户ID. 纸上得来终觉浅 先了解以下几个基本知识: 用户ID包括:实际用户ID.有效用户I ...

  5. 【C&plus;&plus;】获取URL中主机域名

    // ConsoleApplication1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <windows.h& ...

  6. FPGA设计中的异步复位、同步释放思想

    1.一个简单的异步复位例子: module test( input clk, input rst_n, input data_in, output reg out ); always@(posedge ...

  7. lecture7图像检索-七月在线-cv

    http://blog.csdn.net/u014568921/article/details/52518587 图像相似性搜索的原理 BOW 原理及代码解析 Bag Of Visual Words ...

  8. Django商城项目笔记No&period;8用户部分-注册接口实现

    Django商城项目笔记No.8用户部分-注册接口实现 users的view.py中增加如下代码 class RegisterUserView(CreateAPIView): "" ...

  9. git for windows配置SSH key

    0. 前言 之前用过一段时间的git,后来迁移系统导致电脑中的git bash消失了,由于在上家公司版本管理用的svn,所以一直没有重新配置,目前工作中版本管理用的gitLab,后期计划将工作之外的精 ...

  10. select自定义下拉选择图标

    闲言少叙: 上CSS: appearance: none; -moz-appearance: none; -webkit-appearance: none; cursor: pointer; back ...