package com.cnki.client.utils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class ImageLoaderTools {
private HttpTools httptool;
private Context mContext;
//线程轮询的控制变量
private boolean isLoop = true;
//图片缓存集合
private HashMap<String, SoftReference<Bitmap>> mHashMap_caches;
//下载任务队列
private ArrayList<ImageLoadTask> maArrayList_taskQueue;
//用于回调callback中的方法,更新界面
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
ImageLoadTask _task = (ImageLoadTask) msg.obj;
Log.i("info", ""+_task);
//调用callback中的imageloaded方法,通知界面更新数据
_task.callback.imageloaded(_task.path, _task.bitmap);
};
};
//创建工作线程,用于轮询任务队列从而下载图片
private Thread mThread = new Thread(){
public void run() {
while(isLoop){
//当任务队列中有任务时开始执行下载
while(maArrayList_taskQueue.size() >0){
try {
//从任务队列中移除任务时会返回任务对象即得到任务下载对象
ImageLoadTask task = maArrayList_taskQueue.remove(0);
//如果下载的是小图标,就将下载的图片按一定的比例进行相应的缩小
if(Constant.LOADPICTYPE == 1) {
//开始下载,获取图片文件的字节数组
byte[] bytes = httptool.getByte(task.path, null, HttpTools.METHOD_GET);
//获取固定大小的图片,即是经过缩放后的图片,纵横比不变,宽高为40,用来放置图书图片
task.bitmap = BitMapTools.getBitmap(bytes, 40, 40);
//获取图片的原始大小
} else if(Constant.LOADPICTYPE == 2) {
//开始下载,获取图片文件的字节数组
InputStream in = httptool.getStream(task.path, null, HttpTools.METHOD_GET);
//获取固定大小的图片,即是经过缩放后的图片,纵横比不变,宽高为40,用来放置图书图片
task.bitmap = BitMapTools.getBitmap(in, 1);
//Log.i("info", "task.bitmap============"+task.bitmap);
}
//如果图片下载成功就向内存缓存和文件中放置缓存信息,以便之后从双缓存中读取图片信息
if(task.bitmap != null){
//向集合缓存中添加缓存
mHashMap_caches.put(task.path,new SoftReference<Bitmap>(task.bitmap) );
//向文件中添加缓存信息
//获取文件存储路径
File dir = mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
//如果文件路径不存在 ,则创建该路径
if(!dir.exists()){
dir.mkdirs();
}
//创建图片存储路径
File file = new File(dir, task.path);
//向该文件路径中存储图片
BitMapTools.saveBitmap(file.getAbsolutePath(), task.bitmap);
//下载完成后发送消息回主线程
Message msg = Message.obtain();
msg.obj = task;
mHandler.sendMessage(msg);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//当前线程处于等待状态
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
};
//构造方法,
public ImageLoaderTools(Context context){
this.mContext = context;
httptool = new HttpTools(context);
mHashMap_caches = new HashMap<String, SoftReference<Bitmap>>();
maArrayList_taskQueue = new ArrayList<ImageLoaderTools.ImageLoadTask>();
mThread.start();
}
/**
* 图片下载任务类
* @author 3gtarena
*
*/
private class ImageLoadTask{
String path;
Bitmap bitmap;
Callback callback;
}
/**
* 回调接口。在调用loadimage方法时,需要传入回调接口的实现类对象
* @author 3gtarena
*
*/
public interface Callback{
void imageloaded(String path,Bitmap bitmap);
}
//结束工作线程,终止线程轮询
public void quit(){
isLoop = false;
}
/**
* 利用图片路径下载图片 利用内存缓存和文件缓存双缓存机制优化下载
* @param path
* @param callback
* @return
*/
public Bitmap imageLoad(String path,Callback callback){
Bitmap bitmap = null;
//如果内存缓存中存在该路径,则从内存中直接获取该图片
if(mHashMap_caches.containsKey(path)){
bitmap = mHashMap_caches.get(path).get();
//如果缓存中的图片已经被释放,则从该缓存中移除图片路径
if(bitmap == null){
mHashMap_caches.remove(path);
}else {
return bitmap;
}
}
//如果缓存中未得到缓存需要的图片,则从文件中读取该图片
//获取本文件的图片类的文件存储路径
File dir = mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
//Log.i("info", "dir=============="+dir);
//创建要获取的图片路径
File file = new File(dir, path);
//从文件中读取指定路径的图片
bitmap = BitMapTools.getBitMap(file.getAbsolutePath());
//如果文件中存在该图片,则直接从文件中获取图片
if(bitmap != null){
return bitmap;
}
//如果两个缓存中都未获取图片,则直接从服务器端下载图片
//创建下载人任务
ImageLoadTask task = new ImageLoadTask();
//设置下载路径
task.path = path;
//设置下载任务的callback对象
task.callback = callback;
//将下载任务添加到任务队列 进入任务轮询状态
maArrayList_taskQueue.add(task);
//唤醒线程,开始下载
synchronized (mThread) {
mThread.notify();
}
return null;
}
}
分享到:
相关推荐
实现图片下载和缓存功能,可以将图片下载之后缓存到内存或者SD卡中。图片第一次从互联网下载之后,就会缓存到内存或者SD卡中。第二次再打开浏览时,就无需再从互联网下载,而是直接从内存或者SD卡中读取。 效果图说...
在Android开发中,异步批量下载图片并缓存是一个常见的需求,特别是在开发涉及大量图片展示的应用时,如社交应用、电商应用等。本教程将基于提供的Android例子源码,深入探讨如何实现这一功能。 首先,我们需要理解...
在iOS开发中,异步加载图片缓存是一个关键的技术点,尤其在处理大量图片数据时,如滚动列表或网格视图。这个小例子旨在演示如何有效地实现这一功能,以优化用户体验,避免因为逐个下载图片导致的应用卡顿。以下是...
"android图片的异步下载和缓存"这个主题涉及到如何高效、流畅地显示图片,避免阻塞UI线程,并且实现图片的本地缓存,提高用户体验。下面我们将详细探讨这两个核心概念。 1. **异步加载**: 在Android中,主线程...
在Android开发中,异步批量下载图片并缓存是一个常见的需求,特别是在开发涉及大量图片展示的应用,如社交媒体、电商应用等。这个过程涉及到网络请求、线程管理、内存优化以及本地存储等多个技术点。以下是对这个...
2. **内存缓存**:缓存图片到内存中可以快速获取,避免重复下载。Android的WeakHashMap或者LruCache可以用来做内存缓存,它们能根据系统内存动态调整缓存大小,防止内存泄漏。 3. **磁盘缓存**:当内存不足以存储...
"Android图片异步加载缓存"是一个关键的技术概念,它涉及到如何有效地管理内存和磁盘资源,优化用户体验,避免因加载大图或频繁加载图片导致应用卡顿甚至崩溃。以下是对这个主题的详细解释: 1. **异步加载**:...
例如,SDWebImage是一个流行的iOS图片加载库,它支持异步下载和缓存图片。使用SDWebImage,我们可以在UIImageView中直接设置图片URL,库会自动处理下载和显示的过程,如下所示: ```swift import SDWebImage ...
总的来说,"android异步加载网络图片,双缓存内存加sd卡缓存 绝对不会出现内存溢出oom"这个主题涉及到的关键技术包括异步编程、内存管理、缓存策略以及图片处理。通过合理的实践和优化,我们可以创建出一个高效、...
总的来说,SDWebImage是iOS开发中处理网络图片不可或缺的工具,它的强大功能和易用性使得开发者能够高效地处理图片加载和缓存,提升应用性能。通过深入理解和灵活运用,我们可以创建出更加流畅、响应快速的应用程序...
本篇将深入探讨如何对ListView进行优化,以及如何实现图片的异步加载和缓存策略,以避免这些问题。 **1. ListView优化** ListView的优化主要涉及以下几个方面: 1.1 **convertView复用机制**:ListView的Adapter...
本文将深入探讨“Android图片异步加载(双缓存)实例”,介绍如何利用线程池管理和实现内存及SD卡双缓存机制,以提高图片加载效率和用户体验。 1. **异步加载图片** 在Android中,图片加载必须在后台线程执行,以...
在实际项目中,我们可以封装一个工具类或服务类,包含初始化线程池、创建Handler实例、异步加载数据到双缓存、以及在主线程更新UI的方法。例如,我们可以创建一个`AsyncDataFetcher`类,包含`fetchData()`方法负责...
综上所述,Android图片异步下载涉及多方面技术,包括线程管理、网络请求库的使用、内存管理和缓存策略、图片解码压缩以及自定义监听回调等。开发者需要结合实际需求,选择合适的工具和方法,确保图片加载既高效又...
在IT行业中,图片缓存工具类是开发移动应用或网页时不可或缺的一部分,它主要用于优化用户体验,提高应用程序性能,特别是对于那些需要频繁加载和显示图片的应用。这个“图片缓存工具类”很可能是一个自定义的Java或...
硬件采用Micron公司的1GB SODIMM DDR3 和Kintex-7系列FPGA的片上FIFO,软件通过研究DDR3的基本工作原理编写用户接口模块,同时结合片上FIFO的控制模块完成异步FIFO缓存系统的设计,通过改变异步FIFO的读写时钟就可以...
总结来说,Afinal框架在Android中实现了图片的简单异步缓存加载,通过后台线程处理网络请求和图片解码,结合内存和磁盘缓存,有效提升了图片加载的效率,改善了用户体验。开发者只需要调用相应的接口,就能轻松地在...
这个“android图片循环显示及异步加载缓存”是一个典型的需求,用于实现高效的图片展示。在这个场景中,图片通常会以轮播或者滑动列表的形式出现,并且需要在后台异步加载以避免阻塞UI线程,同时通过缓存机制提高...
1. **异步加载**:异步加载图片意味着在不阻塞主线程的情况下下载和处理图片。这通常通过使用`Task`、`async/await`关键字以及.NET框架提供的`HttpClient`来实现。例如,你可以创建一个异步方法,调用`HttpClient`的...
本项目是一个批量下载图片的小例子,项目编码UTF-8编译版本4.4.2主要特点有: 1、下载大图decode时,可根据View大小自动缩放图片,不在出现OOM和SkImageDecoder::Factory returned null错误 2、图片下载失败时,可...