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异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图 ...
随机推荐
- 【6.12校内test】T1单词序列
[问题描述] 给出两个单词(开始单词和结束单词)以及一个词典.找出从开始单词转换到结束单词, 所需要的最短转换序列.转换的规则如下: 1.每次只能改变一个字母 2.转换过程中出现的单词(除开始单词和结 ...
- numpy数组的索引和切片
numpy数组的索引和切片 基本切片操作 >>> import numpy as np >>> arr=np.arange(10) >>> arr ...
- P1142轰炸
这是uva上的一道模拟题. 首先给出n(n<=700)个点的坐标(坐标在1*10^9)之内,询问走直线可以经过的点数.一开始我想到了一个类似于桶排序的方法来存坐标,但是要注意数组大小啊!第二次想 ...
- [.net core]5.outProcess
与inProcess比较 OutProcess性能更差,因为此时它使用了两个web服务器 ,内部是kestrel 外部可能是iis apache nginx 等. 使用visual studio ...
- 095、如何创建Swarm集群?(Swarm02)
参考https://www.cnblogs.com/CloudMan6/p/7862254.html 本节我们将创建三节点的swarm集群(操作系统Ubuntu 16.04 ,Docker 版本均 ...
- docker数据卷挂载
docker数据卷挂载笔记 我们的服务运行时必不可少的会产生一些日志,或是我们需要把容器内的数据进行备份,甚至多个容器之间进行数据共享,这必然涉及容器的数据管理操作. 容器中管理数据主要有两种方式: ...
- vscode如何使用?常用插件有哪些?
vscode下载 官网下载:https://code.visualstudio.com/ 一.汉化中文(官方下载默认为英文,英文好的小伙伴可直接跳过这步) 点击插件按钮搜索 Chinese, 在弹出的 ...
- linux下重启tomcat命令
在Linux系统下,重启Tomcat使用命令操作的! 首先,进入Tomcat下的bin目录 cd /usr/local/tomcat/bin 使用Tomcat关闭命令 ./shutdown.sh 查看 ...
- 简单Delphi程序设计
- flex布局总结回顾
1.背景 传统css盒式模型,依赖 display属性 + position属性 + float属性实现页面的布局,而随着互联网的迅猛发展,带动了无数的互联网创业者和互联网产品,因而样式布局的美化成为 ...