`
何先生
  • 浏览: 26508 次
  • 性别: 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 listView图片异步加载(拖动时不加载,双缓存)

    因此,我们需要采用异步加载图片的方式,同时为了优化性能,通常会采用双缓存策略。本文将详细介绍如何在ListView中实现图片的异步加载,并且在用户拖动时不加载,以提高滚动流畅性。 一、异步加载原理 异步加载是...

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

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

    android图片的异步下载和缓存

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

    异步批量下载图片并缓存

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

    ListView的异步加载图片并缓存

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

    android图片异步加载缓存

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

    iOS 图片异步加载 图片缓存

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

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

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

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

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

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

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

    异步加载和缓存

    在iOS开发中,异步加载和缓存是两个至关重要的概念,特别是在处理大量数据和多媒体内容时,如在UITableView或UICollectionView中显示图片。这两个技术能够显著提升应用性能,提高用户体验,同时节省系统资源。 首先...

    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、图片下载失败时,可...

    安卓图片加载缓存相关-图片缓存工程可以实现图片异步下载可设置内存缓存磁盘缓存并可设置下载优先级等各种你想要的大部分功能需求.zip

    这个压缩包“安卓图片加载缓存相关-图片缓存工程可以实现图片异步下载可设置内存缓存磁盘缓存并可设置下载优先级等各种你想要的大部分功能需求.zip”似乎提供了一个完整的解决方案,涵盖了异步下载、内存缓存、磁盘...

Global site tag (gtag.js) - Google Analytics