Android异步载入学习笔记之四:利用缓存优化网络载入图片及ListView载入优化
假设不做不论什么处理。直接用网络载入图片在网速快的情况下可能没什么不好的感觉。可是假设使用移动流量或是网络不好的时候。问题就来了,要么用户会抱怨流量使用太多。要么抱怨图片载入太慢。如论从哪个角度出发,都不是好的体验!
要提高用户体验,我们就要使用缓存。Android中数据缓存的方式有非常多,相关介绍的文章也比較多。比方http://blog.csdn.net/dahuaishu2010_/article/details/17093139和http://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载入优化的更多相关文章
- Android安装器学习笔记(一)
Android安装器学习笔记(一) 一.Android应用的四种安装方式: 1.通过系统应用PackageInstaller.apk进行安装,安装过程中会让用户确认 2.系统程序安装:在开机的时候自动 ...
- 学习笔记:利用GDI+生成简单的验证码图片
学习笔记:利用GDI+生成简单的验证码图片 /// <summary> /// 单击图片时切换图片 /// </summary> /// <param name=&quo ...
- 机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据
机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据 关键字:PCA.主成分分析.降维作者:米仓山下时间:2018-11-15机器学习实战(Ma ...
- Spring MVC 学习笔记2 - 利用Spring Tool Suite创建一个web 项目
Spring MVC 学习笔记2 - 利用Spring Tool Suite创建一个web 项目 Spring Tool Suite 是一个带有全套的Spring相关支持功能的Eclipse插件包. ...
- Oracle学习笔记之四sp1,Oracle 11g的常用函数
从Oracle学习笔记之四,SQL语言入门中摘出来的,独立成一章节 3.1 字符类函数 ASCII(c)和CHR(i) 分别用于返回一个字符的ASCII码和返回给定ASCII值所对应的字符. C ...
- mybatis学习笔记(14)-查询缓存之中的一个级缓存
mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...
- SpringBoot学习笔记:Redis缓存
SpringBoot学习笔记:Redis缓存 关于Redis Redis是一个使用ANSI C语言编写的免费开源.支持网络.可基于内存亦可以持久化的日志型.键值数据库.其支持多种存储类型,包括Stri ...
- 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)
再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...
- [Android]异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3574131.html 这个可以实现ImageView异步加载 ...
随机推荐
- Selenium 的基础框架类
个人写的一个selenium的base类,应该所有使用selenium的同事都会使用到: package com.hx.baserunner; import static java.io.File.s ...
- 7、redis之使用spring集成commons-pool来操作常见数据类型
环境的搭建参见:http://www.cnblogs.com/yangzhilong/p/4729857.html 下面直接贴具体的测试代码: package com.yzl; import java ...
- python 模块之os.path模块
# -*- coding: cp936 -*- #python 27 #xiaodeng #python 模块之os.path模块 #http://www.cnblogs.com/dkblog/arc ...
- 初始化ArrayList的两种方法[转]
方式一: ArrayList<String> list = new ArrayList<String>(); String str01 = String("str ...
- HOOK 底层键盘消息---WH_KEYBOARD_LL
代码:屏蔽三个全局快捷键 代码的作用是屏蔽掉凝视中的三个快捷键. LRESULT CALLBACK LowLevelKeyboardProc (INT nCode, WPARAM wParam, LP ...
- 监听Sms.Content_URI而不是Sms.Inbox.CONTENT_URI
getContentResolver().registerContentObserver(Sms.Inbox.CONTENT_URI, true, newMsgObserver); / ...
- ubuntu安装过程中遇到问题小结
一.下载 官网下载地址:https://www.ubuntu.com/download/desktop/contribute?version=16.04.4&architecture=amd6 ...
- MATLAB 向量
MATLAB 向量: 1.MATLAB 行向量: 创建行向量括在方括号中的元素的集合,用空格或逗号分隔的元素. 2.MATLAB 列向量: 创建列向量括在方括号中的元素的集合,使用分号来分隔的元素. ...
- 【LeetCode】201. Bitwise AND of Numbers Range
Bitwise AND of Numbers Range Given a range [m, n] where 0 <= m <= n <= 2147483647, return ...
- 利用Apache配置http expires值提高网站性能
HTTP头中有个expires参数,设置一个未来的时间,在这时间以前,浏览器会先从cache读取,如果没有再从服务器中读取.对于像图片,css,script等静态内容,只需发一次http reques ...