android图片处理

/**  
 * @Title: BitmapCache.java
 */
package com.zero.imagedispose;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.Hashtable;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

/**
 * @ClassName: BitmapCache
 * @Description: 图片处理,防止溢出
 * @author ZeRo_Ci
 * @date 2014-3-26 下午2:52:05
 * 
 */
public class BitmapCache {
	private static BitmapCache cache;
	/** 用于内同存储 */
	private Hashtable<String, BitmapRef> bitmapRefs;
	/** 垃圾Reference的队列(所引用的对象已经被回收,则将该引用存入队列中 */
	private ReferenceQueue<Bitmap> q;

	/**
	 * 
	 * @ClassName: BitmapRef
	 * @Description: 继承SoftReference,使得每个实例都具有可识别的标识
	 * @author ZeRo_Ci
	 * @date 2014-3-26 下午3:13:39
	 * 
	 */
	class BitmapRef extends SoftReference<Bitmap> {
		private String _key = "";

		public BitmapRef(Bitmap r, ReferenceQueue<Bitmap> q, String key) {
			super(r, q);
			_key = key;
		}
	}

	public BitmapCache() {
		bitmapRefs = new Hashtable<String, BitmapCache.BitmapRef>();
		q = new ReferenceQueue<Bitmap>();
	}

	/**
	 * 取得缓存器实例
	 */
	protected static BitmapCache getInstance() {
		if (cache == null) {
			cache = new BitmapCache();
		}
		return cache;
	}

	/**
	 * 依据所指定的文件名获取图片
	 */
	protected Bitmap getBitmap(String filename, AssetManager assetManager) {
		Bitmap bitmapImage = null;
		// 缓存中是否有该Bitmap实例的软引用,如果有,从软引用中取得。
		if (bitmapRefs.containsKey(filename)) {
			BitmapRef ref = bitmapRefs.get(filename);
			bitmapImage = ref.get();
		}
		// 如果没有软引用,或者从软引用中得到的实例是null,重新构建一个实例,
		// 并保存对这个新建实例的软引用
		if (bitmapImage == null) {
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inTempStorage = new byte[16 * 1024];
		}
		BufferedInputStream stream;
		try {
			/**
			 * BufferedInputStream与BufferedOutputStream的使用  
			 * 
			 * 1.  java.io.BufferedInputStream与java.io.BufferedOutputStream可以为
			 * InputStream,OutputStream类增加缓冲区功能。构建BufferedInputStream实例时,
			 * 需要给定一个InputStream类型的实例
			 * ,实现BufferedInputStream时,实际上最后是实现InputStream实例
			 * 。同样,构建BufferedOutputStream时
			 * ,也需要给定一个OutputStream实例,实现BufferedOutputStream时
			 * ,实际上最后是实现OutputStream实例。 
			 * 
			 *   2. BufferedInputStream的数据成员buf是一个位数组,默认为2048字节
			 * 。当读取数据来源时,例如文件,BufferedInputStream会尽量将buf填满
			 * 。当使用read()方法时,实际上是先读取buf中的数据,而不是直接对数据来源作读取。当buf中的数据不足时,
			 * BufferedInputStream才会再实现给定的InputStream对象的read()方法,从指定的装置中提取数据。  
			 * 
			 * 3. BufferedOutputStream的数据成员buf也是一个位数组,默认为512字节。当使用write()
			 * 方法写入数据时实际上会先将数据写到buf中
			 * ,当buf已满时才会实现给定的OutputStream对象的write()方法,将buf数据写到目的地
			 * ,而不是每次都对目的地作写入的动作
			 */
			stream = new BufferedInputStream(assetManager.open(filename));
			bitmapImage = BitmapFactory.decodeStream(stream);
			this.addCacheBitmap(bitmapImage, filename);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bitmapImage;

	}

	/**
	 * 以软引用的方式对一个Bitmap对象的实例进行引用并保存该引用
	 */
	private void addCacheBitmap(Bitmap bitmap, String key) {

		cleanCache();
		BitmapRef ref = new BitmapRef(bitmap, q, key);
		bitmapRefs.put(key, ref);
	}

	/**
	 * 清理缓存
	 */
	private void cleanCache() {
		BitmapRef ref = null;
		while ((ref = (BitmapRef) q.poll()) != null) {
			bitmapRefs.remove(ref._key);
		}
	}

	/**
	 * 清除Cache中的全部内容
	 */
	private void clearCache() {

		cleanCache();
		bitmapRefs.clear();
		System.gc();
		System.runFinalization();
	}

}


/**  
 * @Title: ImageLoaderTask.java
 */
package com.zero.imagedispose;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;

import com.zero.uitls.TaskParam;

import android.app.ActionBar.LayoutParams;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.widget.ImageView;

/**
 * @ClassName: ImageLoaderTask
 * @Description: 图片加载
 * @author ZeRo_Ci
 * @date 2014-3-26 下午2:52:23
 * 
 */
// AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(
// 以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

public class ImageLoaderTask extends AsyncTask<TaskParam, Void, Bitmap> {
	private TaskParam taskParam;
	/** 防止溢出 */
	private final WeakReference<ImageView> reference;

	public ImageLoaderTask(ImageView imageView) {
		reference = new WeakReference<ImageView>(imageView);
	}

	/**
	 * 参考文献:
	 * 
	 * http://blog.163.com/gobby_1110/blog/static/29281715201352004329356/
	 * http://www.2cto.com/kf/201203/122729.html
	 * http://blog.csdn.net/cjjky/article/details/6684959
	 * 
	 * AsyncTask源码地址 :
	 * https://github.com/android/platform_frameworks_base/blob/master
	 * /core/java/android/os/AsyncTask.java
	 */
	protected Bitmap doInBackground(TaskParam... params) {
		taskParam = params[0];
		return loadImageFile(taskParam.getFilename(),
				taskParam.getAssetManager());
	}

	/**
	 * 加载图片文件
	 */
	private Bitmap loadImageFile(final String filename,
			final AssetManager manager) {
		InputStream inputStream = null;
		try {
			Bitmap bitmap = BitmapCache.getInstance().getBitmap(filename,
					taskParam.getAssetManager());
			return bitmap;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (inputStream != null) {
					inputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
	 */
	@Override
	protected void onPostExecute(Bitmap result) {
		if (isCancelled()) {
			result = null;
		}
		if (reference != null) {
			ImageView imageView = reference.get();
			if (imageView != null) {
				if (result != null) {
					int width = result.getWidth();
					int height = result.getHeight();
					LayoutParams layoutParams = (LayoutParams) imageView
							.getLayoutParams();
					/** 调整高度 */
					layoutParams.height = (height * taskParam.getItemWidth())
							/ width;
					imageView.setLayoutParams(layoutParams);
					imageView.setImageBitmap(result);
				}
			}

		}
	}
}


安卓开发、ios开发、QT移动开发技术交流学习群 347131054  。欢迎有志做移动开发的同行加入!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值