android实现异步加载图片类
其中牵涉到的关键知识点
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实现异步加载图片类的更多相关文章
- Android GridView异步加载图片和加载大量图片时出现Out Of Memory问题
我们在使用GridView或者ListView时,通常会遇到两个棘手的问题: 1.每个Item获取的数据所用的时间太长会导致程序长时间黑屏,更甚会导致程序ANR,也就是Application No R ...
- android listview 异步加载图片并防止错位
网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...
- 又优化了一下 Android ListView 异步加载图片
写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 我也是因为看 ...
- Android 实现异步加载图片
麦洛开通博客以来,有一段时间没有更新博文了.主要是麦洛这段时间因项目开发实在太忙了.今天周六还在公司加班,苦逼程序猿都是这样生活的. 今天在做项目的时候,有一个实现异步加载图片的功能,虽然比较简单但还 ...
- android ListView异步加载图片(双缓存)
首先声明,参考博客地址:http://www.iteye.com/topic/685986 对于ListView,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求... ...
- 转:Android ListView 异步加载图片
http://www.iteye.com/topic/1118828 http://www.iteye.com/topic/1127914 这样做无疑是非常可取的方法,但是加载图片时仍然会感觉到轻微的 ...
- android异步加载图片并缓存到本地实现方法
图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略.今天首先介绍一下本地缓存图片 在android项目中访问网络图片是非常普遍性的事 ...
- Android学习笔记(二)之异步加载图片
最近在android开发中碰到比较棘手的问题,就是加载图片内存溢出.我开发的是一个新闻应用,应用中用到大量的图片,一个界面中可能会有上百张图片.开发android应用的朋友可能或多或少碰到加载图片内存 ...
- Android的ListView异步加载图片时,错位、重复、闪烁问题的分析及解决方法
Android ListView异步加载图片错位.重复.闪烁分析以及解决方案,具体问题分析以及解决方案请看下文. 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图 ...
随机推荐
- xml文件简单读取,循环遍历
xml文件的简单读取出来生成dom4j.Document对象树,循环遍历获取节点 例子: import java.util.Iterator; import org.dom4j.Document; i ...
- C++中的多重继承(一)
1,C++ 中是否允许一个类继承自多个父类? 1,可以: 2,这种情况就是多重继承: 3,多重继承的表象就是一个类有多个父类: 4,这是 C++ 非常特别的一个特性,在其他的程序设计语言中比如 C#. ...
- jquery html select 清空保留第一项
<select id="a"> <option>1</option> <option>2</option> <op ...
- luoguP4578_ [FJOI2018]所罗门王的宝藏
题意 一个n*m的矩阵,初始值全为0,每一行每一列操作一次可以加1或者减1,问能否操作得到给定矩阵. 分析 行和列的分别的加减是可以相互抵消的,因此我们只需要考虑行的加和列的减. 对于给定矩阵每一个数 ...
- 关于hstack和Svstack
关于hstack和Svstack import numpy as np>>> a = np.array((1,2,3))>>> aarray([1, 2, 3])& ...
- paramiko模块(基于SSH用于连接远程服务器)
paramiko模块,基于SSH用于连接远程服务器并执行相关操作 class SSHConnection(object): def __init__(self, host_dict): self.ho ...
- oracle数据库应用总结
1------->>>>>>>>>>>>>>>>>>>>>>> ...
- Min-max theorem
wiki链接
- 深入理解JAVA虚拟机 高效并发
处理器和缓存 由于计算机的存储设备与处理器的运算速度之间有着几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存来作为内存与处理之间的缓冲:将运算需要使用的数 ...
- solaris11 format zpool
# format AVAILABLE DISK SELECTIONS:0. c1t0d0 <LSI-MR9261-8i-2.12-557.86GB>/pci@0,0/pci8086,3c0 ...