`
何先生
  • 浏览: 26438 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

ImageLoaderTools图片异步双缓存下载工具

阅读更多
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;
	}
	
}
分享到:
评论

相关推荐

    BitmapCache-master图片异步下载缓存

    实现图片下载和缓存功能,可以将图片下载之后缓存到内存或者SD卡中。图片第一次从互联网下载之后,就会缓存到内存或者SD卡中。第二次再打开浏览时,就无需再从互联网下载,而是直接从内存或者SD卡中读取。 效果图说...

    Android例子源码异步批量下载图片并缓存

    在Android开发中,异步批量下载图片并缓存是一个常见的需求,特别是在开发涉及大量图片展示的应用时,如社交应用、电商应用等。本教程将基于提供的Android例子源码,深入探讨如何实现这一功能。 首先,我们需要理解...

    IOS异步加载缓存图片

    在iOS开发中,异步加载图片缓存是一个关键的技术点,尤其在处理大量图片数据时,如滚动列表或网格视图。这个小例子旨在演示如何有效地实现这一功能,以优化用户体验,避免因为逐个下载图片导致的应用卡顿。以下是...

    android图片的异步下载和缓存

    "android图片的异步下载和缓存"这个主题涉及到如何高效、流畅地显示图片,避免阻塞UI线程,并且实现图片的本地缓存,提高用户体验。下面我们将详细探讨这两个核心概念。 1. **异步加载**: 在Android中,主线程...

    异步批量下载图片并缓存

    在Android开发中,异步批量下载图片并缓存是一个常见的需求,特别是在开发涉及大量图片展示的应用,如社交媒体、电商应用等。这个过程涉及到网络请求、线程管理、内存优化以及本地存储等多个技术点。以下是对这个...

    ListView的异步加载图片并缓存

    2. **内存缓存**:缓存图片到内存中可以快速获取,避免重复下载。Android的WeakHashMap或者LruCache可以用来做内存缓存,它们能根据系统内存动态调整缓存大小,防止内存泄漏。 3. **磁盘缓存**:当内存不足以存储...

    android图片异步加载缓存

    "Android图片异步加载缓存"是一个关键的技术概念,它涉及到如何有效地管理内存和磁盘资源,优化用户体验,避免因加载大图或频繁加载图片导致应用卡顿甚至崩溃。以下是对这个主题的详细解释: 1. **异步加载**:...

    iOS 图片异步加载 图片缓存

    例如,SDWebImage是一个流行的iOS图片加载库,它支持异步下载和缓存图片。使用SDWebImage,我们可以在UIImageView中直接设置图片URL,库会自动处理下载和显示的过程,如下所示: ```swift import SDWebImage ...

    android异步加载网络图片,双缓存内存加sd卡缓存 绝对不会出现内存溢出oom

    总的来说,"android异步加载网络图片,双缓存内存加sd卡缓存 绝对不会出现内存溢出oom"这个主题涉及到的关键技术包括异步编程、内存管理、缓存策略以及图片处理。通过合理的实践和优化,我们可以创建出一个高效、...

    IOS SDWebImage异步下载缓存图片(支持离线)

    总的来说,SDWebImage是iOS开发中处理网络图片不可或缺的工具,它的强大功能和易用性使得开发者能够高效地处理图片加载和缓存,提升应用性能。通过深入理解和灵活运用,我们可以创建出更加流畅、响应快速的应用程序...

    Android开发之listview优化+图片异步加载缓存+避免图片显示闪烁

    本篇将深入探讨如何对ListView进行优化,以及如何实现图片的异步加载和缓存策略,以避免这些问题。 **1. ListView优化** ListView的优化主要涉及以下几个方面: 1.1 **convertView复用机制**:ListView的Adapter...

    Android图片异步加载(双缓存)实例

    本文将深入探讨“Android图片异步加载(双缓存)实例”,介绍如何利用线程池管理和实现内存及SD卡双缓存机制,以提高图片加载效率和用户体验。 1. **异步加载图片** 在Android中,图片加载必须在后台线程执行,以...

    android 线程池 handler异步刷新 双缓存

    在实际项目中,我们可以封装一个工具类或服务类,包含初始化线程池、创建Handler实例、异步加载数据到双缓存、以及在主线程更新UI的方法。例如,我们可以创建一个`AsyncDataFetcher`类,包含`fetchData()`方法负责...

    android图片异步下载

    综上所述,Android图片异步下载涉及多方面技术,包括线程管理、网络请求库的使用、内存管理和缓存策略、图片解码压缩以及自定义监听回调等。开发者需要结合实际需求,选择合适的工具和方法,确保图片加载既高效又...

    图片缓存工具类

    在IT行业中,图片缓存工具类是开发移动应用或网页时不可或缺的一部分,它主要用于优化用户体验,提高应用程序性能,特别是对于那些需要频繁加载和显示图片的应用。这个“图片缓存工具类”很可能是一个自定义的Java或...

    基于DDR3 SDRAM的大容量异步FIFO缓存系统的设计与实现

    硬件采用Micron公司的1GB SODIMM DDR3 和Kintex-7系列FPGA的片上FIFO,软件通过研究DDR3的基本工作原理编写用户接口模块,同时结合片上FIFO的控制模块完成异步FIFO缓存系统的设计,通过改变异步FIFO的读写时钟就可以...

    Android代码-afinal框架实现图片的简单异步缓存加载.rar

    总结来说,Afinal框架在Android中实现了图片的简单异步缓存加载,通过后台线程处理网络请求和图片解码,结合内存和磁盘缓存,有效提升了图片加载的效率,改善了用户体验。开发者只需要调用相应的接口,就能轻松地在...

    android图片循环显示及异步加载缓存

    这个“android图片循环显示及异步加载缓存”是一个典型的需求,用于实现高效的图片展示。在这个场景中,图片通常会以轮播或者滑动列表的形式出现,并且需要在后台异步加载以避免阻塞UI线程,同时通过缓存机制提高...

    xamarin异步加载并缓存图片库

    1. **异步加载**:异步加载图片意味着在不阻塞主线程的情况下下载和处理图片。这通常通过使用`Task`、`async/await`关键字以及.NET框架提供的`HttpClient`来实现。例如,你可以创建一个异步方法,调用`HttpClient`的...

    异步批量下载图片并缓存源码.zip

    本项目是一个批量下载图片的小例子,项目编码UTF-8编译版本4.4.2主要特点有: 1、下载大图decode时,可根据View大小自动缩放图片,不在出现OOM和SkImageDecoder::Factory returned null错误 2、图片下载失败时,可...

Global site tag (gtag.js) - Google Analytics