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.24校内test】T2 不老梦
[题目背景] 于万人中万幸得以相逢,刹那间澈净明通. 成为我所向披靡的勇气和惶恐,裂山海,堕苍穹. 爱若执炬迎风,炽烈而哀恸,诸般滋味皆在其中. 韶华宛转吟诵,苍凉的光荣,急景凋年深情难共. ——银临 ...
- map member functions
http://www.cplusplus.com 搜了才发现map的成员函数这么多orz,跟着cplusplus按字典序走一遍叭(顺序有微调orz <1> map::at (c++11) ...
- MySQL数据库创建时间和更新时间错乱问题
在数据中勾选create_time和update_time不为空可以解决更新记录时,create_time也被更新的毛病
- phpstorm配置phpunit进行单元测试
1.配置单元测试目录: (1)autoload.php <?php function autoloader($dir){ spl_autoload_register(function($name ...
- CSP-S全国模拟赛第三场 【nan死了】
mmt 居然第一步膜化乘除 都没看出来,没救了... 大概是贡献前缀和优化的做法 巨兔式讲解:大家都学会了么? 咱发现有大量的 (i/j , i%j ) 同时 对很多 c 产生了贡献,咱可以去优化这一 ...
- vue.js(2)--v-cloak v-text v-html
v-cloak v-text v-html的使用 (1)实例 <!DOCTYPE html> <html lang="en"> <head> ...
- PHP实现无限极分类的两种方式
无限极分类说简单点就是一个类可以分成一个分子类,然后一个子类又可以分另一个子类这样无限分下去,就是好象windows可以新建一个文件夹,然后在这个文件夹里又可以建一个文件夹,PHP要实现无限极分类有两 ...
- 01.LNMP架构-Nginx源码包编译部署详细步骤
操作系统:CentOS_Server_7.5_x64_1804.iso 部署组件:Pcre+Zlib+Openssl+Nginx 操作步骤: 一.创建目录 [root@localhost ~]# mk ...
- Java并发(基础知识)—— 创建、运行以及停止一个线程
在计算机世界,当人们谈到并发时,它的意思是一系列的任务在计算机中同时执行.如果计算机有多个处理器或者多核处理器,那么这个同时性是真实发生的:如果计算机只有一个核心处理器那么就只是表面现象. 现代所有的 ...
- HDU 6215 Brute Force Sorting 模拟双端链表
一层一层删 链表模拟 最开始写的是一个一个删的 WA #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) mem ...