package cn.wangmeng.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class AsyncImageLoader {
private static final String TAG="AsyncImageLoader";

private HashMap<String, SoftReference<Drawable>> imageCache;
private BlockingQueue queue ;
private ThreadPoolExecutor executor ;

public AsyncImageLoader() {
imageCache = new HashMap<String, SoftReference<Drawable>>();

// 线程池:最大50条,每次执行:1条,空闲线程结束的超时时间:180秒
queue = new LinkedBlockingQueue();
executor = new ThreadPoolExecutor(1, 50, 180, TimeUnit.SECONDS, queue);
}

public Drawable loadDrawable(final Context context, final String imageUrl, final ImageCallback imageCallback) {
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
Drawable drawable = softReference.get();
if (drawable != null) {
return drawable;
}
}
final Handler handler = new Handler() {
public void handleMessage(Message message) {
imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
}
};

// 用线程池来做下载图片的任务
executor.execute(new Runnable() {
@Override
public void run() {
Drawable drawable = loadImageFromUrl(context, imageUrl);
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
}
});

return null;
}

// 网络图片先下载到本地cache目录保存,以imagUrl的图片文件名保存。如果有同名文件在cache目录就从本地加载
public static Drawable loadImageFromUrl(Context context, String imageUrl) {
Drawable drawable = null;
if(imageUrl == null )
return null;
String imagePath = "";
String fileName = "";

// 获取url中图片的文件名与后缀
if(imageUrl!=null&&imageUrl.length()!=0){
fileName = imageUrl.substring(imageUrl.lastIndexOf("/")+1);
}

// 图片在手机本地的存放路径,注意:fileName为空的情况
imagePath = context.getCacheDir() + "/" + fileName;

// Log.i(TAG,"imagePath = " + imagePath);
File file = new File(context.getCacheDir(),fileName);// 保存文件
// Log.i(TAG,"file.toString()=" + file.toString());
if(!file.exists()&&!file.isDirectory())
{
try {
// 可以在这里通过文件名来判断,是否本地有此图片

FileOutputStream fos=new FileOutputStream( file );
InputStream is = new URL(imageUrl).openStream();
int data = is.read();
while(data!=-1){
fos.write(data);
data=is.read();;
}
fos.close();
is.close();
// drawable = Drawable.createFromStream(
// new URL(imageUrl).openStream(), file.toString() ); // (InputStream) new URL(imageUrl).getContent();
drawable = Drawable.createFromPath(file.toString());
// Log.i(TAG, "file.exists()不文件存在,网上下载:" + drawable.toString());
} catch (IOException e) {
Log.e(TAG, e.toString() + "图片下载及保存时出现异常!");
}
}else
{
drawable = Drawable.createFromPath(file.toString());
// Log.i("test", "file.exists()文件存在,本地获取");
}
return drawable ;
}

public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable, String imageUrl);
}

}

package cn.wangmeng.test;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

/**
* 图片异步下载的Activity类
*
*
* @author Tim http://doinone.iteye.com/blog/
* @created 2011-6-22
* @since 2011-6-22
*/

public class AsyncListImage extends Activity {
private ListView list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list=(ListView)findViewById(R.id.list);
List<ImageAndText> dataArray=new ArrayList<ImageAndText>();
ImageAndText test=new ImageAndText("http://www.wangmeng.cn/images/logo.gif", "test");
ImageAndText test1=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test1");
ImageAndText test2=new ImageAndText("http://www.wangmeng.cn/images/ad/t3.gif", "test2");
ImageAndText test3=new ImageAndText("http://www.wangmeng.cn/images/ad/logo.gif", "test3"); // 错误的图片url
ImageAndText test4=new ImageAndText("http://www.wangmeng.cn/images/ad/t22223.gif", "test4:错误的图片url");// 错误的图片url
ImageAndText test5=new ImageAndText("http://www.wangmeng.cn/images/ad/t222223.gif", "test5:错误的图片url");// 错误的图片url
ImageAndText test6=new ImageAndText("http://www.wangmeng.cn/images/logo.gif", "test6");
ImageAndText test7=new ImageAndText("http://www.wangmeng.cn/images/ad/t3.gif", "test7");
ImageAndText test8=new ImageAndText("http://www.wangmeng.cn/images/ad/t3.gif", "test8");
ImageAndText test9=new ImageAndText("http://www.wangmeng.cn/images/ad/t2222.gif", "test9:错误的图片url");// 错误的图片url
ImageAndText test10=new ImageAndText("http://www.wangmeng.cn/images/ad/t3.gif", "test10");
ImageAndText test11=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test11");
ImageAndText test12=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test12");
ImageAndText test13=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test13");
ImageAndText test14=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test14");
ImageAndText test15=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test15");
ImageAndText test16=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test16");
ImageAndText test17=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test17");
ImageAndText test18=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test18");

ImageAndText test19=new ImageAndText("", "test19:错误的图片url");

dataArray.add(test);
dataArray.add(test1);
dataArray.add(test2);
dataArray.add(test3);
dataArray.add(test4);
dataArray.add(test5);
dataArray.add(test6);
dataArray.add(test7);
dataArray.add(test8);
dataArray.add(test9);
dataArray.add(test10);
dataArray.add(test11);
dataArray.add(test12);
dataArray.add(test13);
dataArray.add(test14);
dataArray.add(test15);
dataArray.add(test16);
dataArray.add(test17);
dataArray.add(test18);
dataArray.add(test19);
dataArray.add(test2);
ImageAndTextListAdapter adapter=new ImageAndTextListAdapter(this, dataArray, list);
list.setAdapter(adapter);

}
}

package cn.wangmeng.test;

/**
* 保存ListView的item的实体
*
*
* @author Tim http://doinone.iteye.com/blog/
* @created 2011-6-22
* @since 2011-6-22
*/

public class ImageAndText {
private String imageUrl;
private String text;

public ImageAndText(String imageUrl, String text) {
this.imageUrl = imageUrl;
this.text = text;
}
public String getImageUrl() {
return imageUrl;
}
public String getText() {
return text;
}
}

package cn.wangmeng.test;

import java.util.List;

import cn.wangmeng.test.AsyncImageLoader.ImageCallback;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

/**
* 图片异步下载类
* (如该图片已存在即显示图片,否则通过URL下载图片并显示)
*
* @author Tim http://doinone.iteye.com/blog/
* @created 2011-6-22
* @since 2011-6-22
*/

public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {

private ListView listView;
private AsyncImageLoader asyncImageLoader;
private LayoutInflater inflater ;
private Context context;

public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {
super(activity, 0, imageAndTexts);
this.listView = listView;
asyncImageLoader = new AsyncImageLoader();
inflater = activity.getLayoutInflater();
this.context = activity;
}

public View getView(int position, View convertView, ViewGroup parent) {
// Activity activity = (Activity) getContext();

Holder holder ;

if (convertView == null) {
convertView = inflater.inflate(R.layout.image_and_text_row, null);
holder = new Holder();
holder.imageView = (ImageView) convertView.findViewById(R.id.image);
holder.textView = (TextView)convertView.findViewById(R.id.text);

convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}

// 获取item对应第几条(position)的Model实体
ImageAndText imageAndText = getItem(position);

// Load the image and set it on the ImageView
String imageUrl = imageAndText.getImageUrl();
holder.imageView.setTag(imageUrl);

// 延遲加載圖片 : imageUrl 是 圖片的http鏈接地址,後面是回调函數
Drawable cachedImage = asyncImageLoader.loadDrawable(context, imageUrl, new ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
Log.i("test", "Drawable cachedImage = asyncImageLoader.loadDrawable( )-->");
if (imageViewByTag != null && imageDrawable != null ) { // 防止图片url获取不到图片是,占位图片不见了的情况
imageViewByTag.setImageDrawable(imageDrawable);
}
}
});
if (cachedImage == null) {
holder.imageView.setImageResource(R.drawable.default_image);
}else{
holder.imageView.setImageDrawable(cachedImage);
}

// Set the text on the TextView
holder.textView.setText(imageAndText.getText());

Log.i("test","position = " + position);

return convertView;
}

static class Holder{
ImageView imageView;
TextView textView;
}

}

listView异步处理图片下载缓存的更多相关文章

  1. wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)

    wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...

  2. 使用开源库 SDWebImage 异步下载缓存图片(持续更新)

    source  https://github.com/rs/SDWebImage APIdoc  http://hackemist.com/SDWebImage/doc Asynchronous im ...

  3. Android ListView异步载入图片乱序问题,原因分析及解决方式

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android全部系统自带的控件其中,ListView这个控件算是 ...

  4. android listview 异步加载图片并防止错位

    网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...

  5. ListView异步加载图片,完美实现图文混排

    昨天参加一个面试,面试官让当场写一个类似于新闻列表的页面,文本数据和图片都从网络上获取,想起我还没写过ListView异步加载图片并实现图文混排效果的文章,so,今天就来写一下,介绍一下经验. Lis ...

  6. Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...

  7. Android的ListView异步加载图片时,错位、重复、闪烁问题的分析及解决方法

    Android ListView异步加载图片错位.重复.闪烁分析以及解决方案,具体问题分析以及解决方案请看下文. 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图 ...

  8. listview异步加载图片并防止错位

    android listview 异步加载图片并防止错位 网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 conver ...

  9. 异步图片下载引擎(升级版——ExecutorService+handler)

    [Android分享] 异步图片下载引擎(升级版——ExecutorService+handler)  [复制链接]     皮诺 13 主题 5 好友 844 积分 No.4 中级开发者 升级  2 ...

随机推荐

  1. ASP.NET 去除所有HTML标记的方法

    using System.Text.RegularExpressions /// <summary> /// 去除HTML标记 /// </summary> /// <p ...

  2. <label>标签for属性的妙用

    在用户注册的时候,常常用户点击文字就需要将光标聚焦到对应的表单上面,这个是怎么实现的呢?就是下面我要介绍的<label>标签的for属性 定义:for 属性规定 label 与哪个表单元素 ...

  3. Qt增加webp格式支持

    Webp 是一种图片文件格式,能在相同质量的情况下比 PNG 文件尺寸小巧. Chrome 应用商店图片已全部转换为 WebP 格式 YY(基于Qt开发)也已经把图片格式换成webp了 http:// ...

  4. QTP自学攻略

    QTP自学攻略 自学总是很痛苦的,看大量的书籍,可是学到的东西却不是那么实用,下面整理了一些在QTP中经常需要的函数,以及方法很实用!  QTP常用函数  1, 获取对话框相应的文字: GetVisi ...

  5. 关于 未能加载文件或程序集“MySql.Web, Version=6.7.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d”或它的某一个依赖项。系统找不到指定的文件。

    我这个项目是MVC4的,有两个版本,第一个版本直接运行没什么问题,但是跑第二个版本的时候就给我提示这个错误.好吧,百度果然是万能的.下边是解决方案. 1.找到 C:\Windows\Microsoft ...

  6. Android 自学之选项卡TabHost

    选项卡(TabHost)是一种非常实用的组件,TabHost可以很方便地在窗口上放置多个标签页,每个标签页相当于获得了一个与外部容器相同大小的组建摆放区域.通过这种方式,就可以在一个容器中放置更多组件 ...

  7. Java HashCode方法

    有许多人学了很长时间的Java,但一直不明白hashCode方法的作用,  我来解释一下吧.首先,想要明白hashCode的作用,你必须要先知道Java中的集合.   总的来说,Java中的集合(Co ...

  8. Ionic条码扫描

    http://m.blog.csdn.net/article/details?id=45843819

  9. Ehcache(2.9.x) - API Developer Guide, Searching a Cache

    About Searching The Search API allows you to execute arbitrarily complex queries against caches. The ...

  10. Ghost版Win8.1系统企业版下载

    host版Win8.1系统企业版,下载完成后一定要使用校验工具验证GHO文件MD5值,如果不符请不要安装,不然安装失败后果自负.GHO文件路径一定不要带中文,否则无法安装.安装完成第一次进入桌面会黑屏 ...