其中牵涉到的关键知识点

1,回调机制,不过回调接口的实现方式有多种多样,可以是一个类继承该接口,也可以是作为一个方法参数;

可以参照自己的这篇博客:

http://www.cnblogs.com/bobodeboke/archive/2013/04/24/3040662.html

2,hashmap联通softReference实现缓存机制。

3,注意这种回调的处理,首先图片是用的默认图片(这里是应用图标进行占位),当回调接口调用时候,替换为网络获得的图片。

详见代码:

package com.bobo.myimageloader.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap; import android.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView; //异步加载工具类
public class AsycImageLoader { private Context mContext;
// 用来缓存图片信息 private HashMap<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
private Bitmap defbitmap;
private String LOG_TAG = "AsycImageLoader"; // 异步加载图片工具类,如果异步加载不成功就返回图标文件
public AsycImageLoader(Context context) {
this.mContext = context;
// 默认的图片
this.defbitmap = BitmapFactory.decodeResource(mContext.getResources(),
com.bobo.myimageloader.R.drawable.ic_launcher); } /**
* 从sd卡中异步加载图片
*
* @param uri图片所在的文件路径
* @param imageView显示图片的imageview
* @param imageCallBack图片的回调接口
* @return
*/
private Bitmap loadBitmapFormSD(final String uri,
final ImageView imageView, final ImageCallBack imageCallBack,
final int optsize) {
if (this.imageCache.containsKey(uri)) {
SoftReference<Bitmap> softReference = this.imageCache.get(uri);
Bitmap bitmap = softReference.get();
if (bitmap != null) {
return bitmap;
}
}
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
// 调用回调接口
imageCallBack.imageLoaded((Bitmap) msg.obj, imageView);
}
};
// 从文件路径总加载相对费时,因此开启线程进行操作
new Thread() {
public void run() {
Bitmap bitmap = null;
if ((new File(uri)).isFile()) {
// 说明对应路径有错
bitmap = BitmapFactory.decodeResource(
mContext.getResources(),
com.bobo.myimageloader.R.drawable.ic_launcher);
}
bitmap = getBitmapFromFile(uri, optsize);
imageCache.put(uri, new SoftReference<Bitmap>(bitmap));
/*
* Message msg=new Message(); msg.obj=bitmap;
*/
Message msg = handler.obtainMessage(0, bitmap);
handler.sendMessage(msg); }
}.start();
return defbitmap;
} /**
* 从文件路径中获取文件可以设定opt参数
*
* @param uri
* @return
*/ private Bitmap getBitmapFromFile(String uri, int opsize) {
System.out.println("取出文件的路径是:"+uri);
BitmapFactory.Options opt = new BitmapFactory.Options();
// 设置缩放比例,如果设置为2,则图像会是原来的1/2
opt.inSampleSize = opsize;
opt.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(uri, opt);
if (bitmap != null) {
return bitmap;
}
return this.defbitmap;
} private Bitmap loadBitmapFromNet(final String uri,
final ImageView imageView, final ImageCallBack imageCallBack,
final int optsize) {
if (imageCache.containsKey(uri)) {
SoftReference<Bitmap> soft = imageCache.get(uri);
Bitmap bitmap = soft.get();
return bitmap;
} // 如果没有需要开启线程进行下载
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
imageCallBack.imageLoaded((Bitmap) msg.obj, imageView);
}
};
new Thread() {
public void run() {
Bitmap bitmap = null; try {
String savePath = getFileSavePath();
downLoadImageFormNet(uri, savePath); bitmap = getBitmapFromFile(savePath, optsize);
imageCache.put(uri, new SoftReference<Bitmap>(bitmap));
Message msg=handler.obtainMessage(0, bitmap);
handler.sendMessage(msg);
} catch (Exception e) {
Log.d(LOG_TAG, "从网络下载保存bitmap失败");
bitmap = BitmapFactory.decodeResource(
mContext.getResources(),
com.bobo.myimageloader.R.drawable.ic_launcher); } }
}.start(); return defbitmap;
} // 从网络下载并且保存图片资源
protected void downLoadImageFormNet(String uri, String savePath) {
// 如果下载的就是不做处理的原始文件
Bitmap bitmap = null;
try { bitmap = BitmapFactory.decodeStream((new URL(uri)).openStream());
FileOutputStream fos = new FileOutputStream(savePath);
bitmap.compress(CompressFormat.JPEG, 100, fos);
} catch (Exception e) {
Log.d(LOG_TAG, "网络下载或保存文件失败");
e.printStackTrace();
} } protected String getFileSavePath() {
String fileName = new SimpleDateFormat("yyyyMMdd hhmmss")
.format(new Date());
String path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ File.separator
+ "myAsycImage"
+ File.separator
+ "IMG_"
+ fileName + ".jpg";
File file = new File(path);
if (!file.getParentFile().exists()) {
if (!file.getParentFile().mkdirs()) {
return null;
}
}
try {
file.createNewFile();
Log.d(LOG_TAG, file.getAbsolutePath());
return file.getAbsolutePath();
} catch (IOException e) { e.printStackTrace();
return null;
} } // 定义一个回调接口
private interface ImageCallBack {
void imageLoaded(Bitmap bitmap, ImageView imageView);
} /**
* 外部调用接口
*
* @param uri
* 网路上的图片地址
* @param imageView
* 需要显示图片的image控件
* @param callback
*/
public void setAsycImageFromNet(String uri, ImageView imageView) {
if (uri == null) {
return;
} imageView.setImageBitmap(loadBitmapFromNet(uri, imageView,
new ImageCallBack() { @Override
public void imageLoaded(Bitmap bitmap, ImageView imageView) {
imageView.setImageBitmap(bitmap);
} }, 2));
} public void setAsycImageFromSD(String path, ImageView imageView) {
if (path == null) {
return;
}
// 感觉是先用默认图片进行占位,等获取到图片再使用网路上的图片
imageView.setImageBitmap(loadBitmapFormSD(path, imageView,
new ImageCallBack() { @Override
public void imageLoaded(Bitmap bitmap, ImageView imageView) {
imageView.setImageBitmap(bitmap);
} }, 2)); } // 因为本地加载图片的时间开销小,因此可以不进行异步加载
public void setImageFromSD(String path, ImageView imageView) {
imageView.setImageBitmap(BitmapFactory.decodeFile(path)); }
}

android实现异步加载图片类的更多相关文章

  1. Android GridView异步加载图片和加载大量图片时出现Out Of Memory问题

    我们在使用GridView或者ListView时,通常会遇到两个棘手的问题: 1.每个Item获取的数据所用的时间太长会导致程序长时间黑屏,更甚会导致程序ANR,也就是Application No R ...

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

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

  3. 又优化了一下 Android ListView 异步加载图片

    写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 我也是因为看 ...

  4. Android 实现异步加载图片

    麦洛开通博客以来,有一段时间没有更新博文了.主要是麦洛这段时间因项目开发实在太忙了.今天周六还在公司加班,苦逼程序猿都是这样生活的. 今天在做项目的时候,有一个实现异步加载图片的功能,虽然比较简单但还 ...

  5. android ListView异步加载图片(双缓存)

    首先声明,参考博客地址:http://www.iteye.com/topic/685986 对于ListView,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求... ...

  6. 转:Android ListView 异步加载图片

    http://www.iteye.com/topic/1118828 http://www.iteye.com/topic/1127914 这样做无疑是非常可取的方法,但是加载图片时仍然会感觉到轻微的 ...

  7. android异步加载图片并缓存到本地实现方法

    图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略.今天首先介绍一下本地缓存图片     在android项目中访问网络图片是非常普遍性的事 ...

  8. Android学习笔记(二)之异步加载图片

    最近在android开发中碰到比较棘手的问题,就是加载图片内存溢出.我开发的是一个新闻应用,应用中用到大量的图片,一个界面中可能会有上百张图片.开发android应用的朋友可能或多或少碰到加载图片内存 ...

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

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

随机推荐

  1. HDU-1204-糖果大战

    题目描述 生日\(Party\)结束的那天晚上,剩下了一些糖果,\(Gandon\)想把所有的都统统拿走,\(Speakless\)于是说:"可以是可以,不过我们来玩\(24\)点,你不是已 ...

  2. Python 把较长的一行代码分成多行的技巧

    概述:在写代码过程中,经常遇到一行代码很长的情况.为了让代码显得整齐干净,就需要把一行代码分成多行来写,Python中有三种小技巧可以实现该功能:        1.用反斜杠\链接多行代码 示例:   ...

  3. selenium与页面交互之二:webelement类的属性

    webelement类的属性如下: element.size()   获取元素的大小 element.tag_name() 获取元素的HTML标签名称 element.text()   获取元素的文本 ...

  4. hdu2444The Accomodation of Students (最大匹配+判断是否为二分图)

    题意 首先判断所有的人可不可以分成两部分,每部分内的所有人都相互不认识.如果可以分成 则求两部分最多相互认识的对数. 解题 类似分成两组,同组互不相关,就可能使判断是否为二分图 能否分成两部分 则是判 ...

  5. javascript高级程序设计读书笔记-事件(一)

    读书笔记,写的很乱   事件处理程序   事件处理程序分为三种: 1.html事件2. DOM0级,3,DOM2级别  没有DOM1 同样的事件 DOM0会顶掉html事件   因为他们都是属性  而 ...

  6. 缓存---CDN(内容分发网络)

    4.CDN   内容分发网络(content distribution network,CDN)是一种互联的网络系统,它利用更靠近用户的服务器从而更快更可靠的将静态资源分发给用户. cdn主要有以下优 ...

  7. 错误 “SCRIPT7002: XMLHttpRequest: 网络错误 0x2ef3, ie浏览器兼容问题

    参考:https://www.telerik.com/blogs/help!-running-fiddler-fixes-my-app- https://www.cnblogs.com/OpenCod ...

  8. Django设置 DEBUG=False后静态文件无法加载

    修改setting.py STATIC_URL = '/static/' STATIC_ROOT = 'static' ## 新增行 STATICFILES_DIRS = [ os.path.join ...

  9. 工具使用——VMware安装及使用

    一.VMware的安装 本文使用VMware 14 pro,双击打开安装包,点击下一步: 选中我接受许可协议中的条款,点击下一步: 选择安装路径,点击下一步: 点击下一步: 点击下一步: 点击安装: ...

  10. 使用 gitolite 管理配置 git 库的权限

    问题:每次创建git库都需要在gitolite的配置文件中添加git库的配置信息,为了方便管理git库,不在重复提交,所以修改gitolite的配置管理文件. 环境:ubuntu16.04 安装git ...