假设不做不论什么处理。直接用网络载入图片在网速快的情况下可能没什么不好的感觉。可是假设使用移动流量或是网络不好的时候。问题就来了,要么用户会抱怨流量使用太多。要么抱怨图片载入太慢。如论从哪个角度出发,都不是好的体验!

要提高用户体验,我们就要使用缓存。Android中数据缓存的方式有非常多,相关介绍的文章也比較多。比方http://blog.csdn.net/dahuaishu2010_/article/details/17093139http://www.jb51.net/article/38162.htm等。今天学习是是Lru缓存。

Lru(Least Recently Used)近期最少使用算法,即是在一定条件下LRU缓存是把近期最少使用的数据移除。让给最新读取的数据。而往往最常读取的,也是读取次数最多的。所以。利用LRU缓存,我们可以提高应用的效率及用户体验度。Andorid本身提供了LruCache类来实现这个缓存算法 。

在ImageLoader中利用LruCache缓存:

public class ImageLoader {

private LruCache<String, Bitmap> mCaches;// 创建LruCache对象

private ImageView mImageView;

private ListView listView;

private Set<ImageAsyncTask> mTask;





@SuppressLint("NewApi")

public ImageLoader(ListView listView) {

this.listView = listView;

mTask = new HashSet<ImageAsyncTask>();

int maxMemory = (int) Runtime.getRuntime().maxMemory();// 获取最大可用内存

int cacheSize = maxMemory / 8;// 设置缓存数据的最大占用内存量为最大值1/8

mCaches = new LruCache<String, Bitmap>(cacheSize) {

@Override

protected int sizeOf(String key, Bitmap value) {

return value.getByteCount();// 每次存入缓存的时候调用,返回bitmap的大小

}

};

}





@SuppressLint("NewApi")

/**

* 添加缓存数据。添加前推断数据是否存在

* @description:

* @author ldm

* @date 2015-8-11 下午7:51:04

*/

public void setLruCaches(String url, Bitmap bitmap) {

if (getLruCaches(url) == null) {// 假设缓存中不存在url相应的Bitmap。则把bitmap增加mCaches

mCaches.put(url, bitmap);

}

}





/**

* 从缓存中获取数据

* @description:

* @author ldm

* @date 2015-8-11 下午7:51:22

*/

@SuppressLint("NewApi")

public Bitmap getLruCaches(String url) {

return mCaches.get(url);// 通过url获取缓存中相应的bitmap





}





/**

*从url中获取到Bitmap

* @description:

* @author ldm

* @date 2015-8-11 下午1:55:12

*/

public Bitmap getBitmapByUrl(String urlStr) {

Bitmap bitmap = null;

InputStream is = null;

try {

URL url = new URL(urlStr);

HttpURLConnection con = (HttpURLConnection) url.openConnection();

is = new BufferedInputStream(con.getInputStream());

bitmap = BitmapFactory.decodeStream(is);

con.disconnect();

return bitmap;

}

catch (Exception e) {

e.printStackTrace();

}

finally {

try {

is.close();

}

catch (IOException e) {

e.printStackTrace();

}

}

return null;

}





public void loadImgByAsyncTask(ImageView img, String url) {

mImageView = img;

// 从缓存中取出图片

Bitmap bitmap = getLruCaches(url);

if (bitmap == null) {// 假设能在中无图片,则就从网络下载

mImageView.setImageResource(R.drawable.ic_launcher);//设置默认图片

new ImageAsyncTask(url).execute(url);

}

else {// 缓存中有图片。则直接显示出来

mImageView.setImageBitmap(bitmap);

}

}





private class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {

private ImageView imageView;

private String mUrl;





public ImageAsyncTask(String mUrl) {

this.mUrl = mUrl;

}





@Override

protected Bitmap doInBackground(String... params) {

Bitmap bitmap = getBitmapByUrl(params[0]);// 获取图片

if (bitmap != null) {

setLruCaches(params[0], bitmap);

}

return getBitmapByUrl(params[0]);

}





@Override

protected void onPostExecute(Bitmap result) {

ImageView img = (ImageView) listView.findViewWithTag(mUrl);

if (img != null && result != null) {

imageView.setImageBitmap(result);

}

mTask.remove(this);

}

}





public void setImageView(int start, int end) {

for (int i = start; i < end; i++) {

String url = DataAdapter.URLS[i];

Bitmap bitmap = getLruCaches(url);

if (bitmap == null) {// 假设能在中无图片,则就从网络下载

ImageAsyncTask task = new ImageAsyncTask(url);

task.execute(url);

mTask.add(task);

}

else {// 缓存中有图片,则直接显示出来

ImageView img = (ImageView) listView.findViewWithTag(url);

img.setImageBitmap(bitmap);

}

}

}

public void stopAllTask(){

if(mTask.size()>0){

for (ImageAsyncTask task : mTask) {

task.cancel(false);

}

}

}

}

相应ListView的数据适配器DataAdapter:

public class DataAdapter extends BaseAdapter implements OnScrollListener {

private Context mContext;

private List<DataBean> list;

private ImageLoader mImageLoader;

private int mSart;

private int mEnd;

public static String[] URLS;

private ListView listView;

private boolean isFirst;//是否是第一次进入 

public DataAdapter(Context mContext, List<DataBean> list, ListView listView) {

this.listView = listView;

this.mContext = mContext;

this.list = list;

mImageLoader = new ImageLoader(listView);

URLS = new String[list.size()];

for (int i = 0; i < list.size(); i++) {

URLS[i] = list.get(i).getImgUrl();

}

isFirst=true;

listView.setOnScrollListener(this);

}



@Override

public int getCount() {

// TODO Auto-generated method stub

return list.size();

}



@Override

public Object getItem(int arg0) {

// TODO Auto-generated method stub

return list.get(arg0);

}



@Override

public long getItemId(int arg0) {

// TODO Auto-generated method stub

return arg0;

}



@Override

public View getView(int arg0, View view, ViewGroup arg2) {

ViewHolder holder = null;

if (view == null) {

holder = new ViewHolder();

view = LayoutInflater.from(mContext).inflate(R.layout.item_layout, null);

holder.iv = (ImageView) view.findViewById(R.id.item_iv);

holder.titleTv = (TextView) view.findViewById(R.id.item_title);

holder.contentTv = (TextView) view.findViewById(R.id.item_content);

view.setTag(holder);

}

else {

holder = (ViewHolder) view.getTag();

}

holder.titleTv.setText(list.get(arg0).getTitle());

holder.contentTv.setText(list.get(arg0).getContent());

holder.iv.setTag(list.get(arg0).getImgUrl());// 为ImageView设置tag

// new ImageLoader().loaderImageThread(holder.iv, list.get(arg0).getImgUrl());//用线程载入图片

mImageLoader.loadImgByAsyncTask(holder.iv, list.get(arg0).getImgUrl());

return view;

}



/***

* ListView在流动过程中调用 

*/

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

mSart = firstVisibleItem;// 可见第一个item

mEnd = firstVisibleItem + visibleItemCount;// 可见的最后一个item

if(isFirst&&visibleItemCount>0){//第一次载入数据时数据处理

mImageLoader.setImageView(mSart, mEnd);

isFirst=false;

}

}



/***

* ListView在流动状态变化时调用 

*/

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

if (scrollState == SCROLL_STATE_IDLE) {// 流动停止,此时载入可见项数据

mImageLoader.setImageView(mSart, mEnd);

}

else {// 停止载入数据

mImageLoader.stopAllTask();

}

}

class ViewHolder {

TextView titleTv;

TextView contentTv;

ImageView iv;

}

}

Android异步载入学习笔记之四:利用缓存优化网络载入图片及ListView载入优化的更多相关文章

  1. Android安装器学习笔记(一)

    Android安装器学习笔记(一) 一.Android应用的四种安装方式: 1.通过系统应用PackageInstaller.apk进行安装,安装过程中会让用户确认 2.系统程序安装:在开机的时候自动 ...

  2. 学习笔记:利用GDI+生成简单的验证码图片

    学习笔记:利用GDI+生成简单的验证码图片 /// <summary> /// 单击图片时切换图片 /// </summary> /// <param name=&quo ...

  3. 机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据

    机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据 关键字:PCA.主成分分析.降维作者:米仓山下时间:2018-11-15机器学习实战(Ma ...

  4. Spring MVC 学习笔记2 - 利用Spring Tool Suite创建一个web 项目

    Spring MVC 学习笔记2 - 利用Spring Tool Suite创建一个web 项目 Spring Tool Suite 是一个带有全套的Spring相关支持功能的Eclipse插件包. ...

  5. Oracle学习笔记之四sp1,Oracle 11g的常用函数

    从Oracle学习笔记之四,SQL语言入门中摘出来的,独立成一章节 3.1 字符类函数 ASCII(c)和CHR(i)    分别用于返回一个字符的ASCII码和返回给定ASCII值所对应的字符. C ...

  6. mybatis学习笔记(14)-查询缓存之中的一个级缓存

    mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...

  7. SpringBoot学习笔记:Redis缓存

    SpringBoot学习笔记:Redis缓存 关于Redis Redis是一个使用ANSI C语言编写的免费开源.支持网络.可基于内存亦可以持久化的日志型.键值数据库.其支持多种存储类型,包括Stri ...

  8. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  9. [Android]异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3574131.html  这个可以实现ImageView异步加载 ...

随机推荐

  1. 菜鸟云打印接入Demo

    菜鸟云打印接入Demo 0. 接入流程图 1. 连接打印客户端 首先要打开打印客户端,然后使用下面的方法,连接客户端(WebSocket协议): 地址 :  连接打印客户端 function doCo ...

  2. 基于Pygame写的翻译方法

    发布时间:2018-11-01   技术:pygame+easygui   概述 实现一个翻译功能,中英文的互相转换.并可以播放翻译后的内容. 翻译接口调用的是百度翻译的api接口. 详细 代码下载: ...

  3. sqlserver几个好用的表值函数和标量函数

    获取逗号风格的字符串中的某一个 比如'1,2,4,5,6' 第三个就是4 CREATE function [dbo].[Get_StrArrayStrOfIndex] ( @str nvarchar( ...

  4. Spring的缺点有哪些--Ext扩展

    http://www.iteye.com/topic/1131284 1.JavaTear2014 --   发表时间:2013-07-17   最后修改:2013-07-17  Spring应用比较 ...

  5. HDFS分布式文件系统(The Hadoop Distributed File System)

    The Hadoop Distributed File System (HDFS) is designed to store very large data sets reliably, and to ...

  6. 由m种数字组成的n位数有多少个

    知乎链接 问题描述 我和我女朋友的QQ号都是九位数字,这九个数字是有七个不同的数字组成的,我想问这种概率是多大,我们是不是特别我看缘分呢?求大神给算一下概率! 思路 定义问题:由7种数字组成的9位数一 ...

  7. 【LeetCode】217. Contains Duplicate (2 solutions)

    Contains Duplicate Given an array of integers, find if the array contains any duplicates. Your funct ...

  8. 魅族MX四核手机转让,二手淘宝上+hi-pda论坛结合使用成功已出

    2013-3-14 内容存档在evernote,笔记名"魅族MX四核手机转让,二手淘宝上+hi-pda论坛结合使用成功已出"

  9. VS2010启动多个实例调试

    项目中经常出现一个解决方案里面有多个程序,如果想按F5启动多个实例进行操作调试那该怎么操作呢? 以前自己都使用附加进程的方法调试,这样的调试不需要按F5,自己只要运行多个程序后,使用vs的附加进程到对 ...

  10. 【HTML】HTML之marquee详解

    该标签不是HTML3.2的一部分,并且只支持MSIE3以后内核,所以如果你使用非IE内核浏览器(如:Netscape)可能无法看到下面一些很有意思的效果该标签是个容器标签语法: <marquee ...