图片相关:bigmap工具类,实现压缩、异步、并发、缓存

1.图片的压缩(图片太大可能会导致内存溢出)


2.图片的异步加载(耗时操作放在工作线程)


3.图片的并发异步加载(实现每个item中imageview对应一个异步任务并绑定一起)


4.图片的缓存问题


bigmap工具类:

public class BitmapUtils {
	/**
	 * 计算压缩比例
	 * 
	 * @param options
	 *            封装图片的实际的高度,宽度
	 * @param reqWidth
	 *            需要的宽度
	 * @param reqHeight
	 *            需求的高度
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		// read height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		// 通过此变量记录压缩比例(1表示不压缩)
		int inSampleSize = 1;
		// 计算压缩比例(假如图片的实际高度,宽度大于我们需要的宽度,高度则要计算压缩比例)
		if (height > reqHeight || width > reqWidth) {
			if (width > height) {
				inSampleSize = Math.round((float) height / (float) reqHeight);
			} else {
				inSampleSize = Math.round((float) width / (float) reqWidth);
			}
		}
		return inSampleSize;
	}

	/** 压缩图片 */
	public static Bitmap decodeSampledBitmapFromResource(String path, int reqWidth, int reqHeight) {

		// First decode with inJustDecodeBounds=true
		// to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;//此值为true表示只读图片边界信息
		// read dimension (height,width)
		BitmapFactory.decodeFile(path, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeFile(path, options);
	}
}

ImageLoaderUtils工具类

实现图片压缩、异步、并发、缓存

public class ImageLoaderUtils {
	
	private static LruCache<String, Bitmap> lruCache;
	
	/**@param size 为缓存空间大小*/
	public static void buildMemoryLruCache(int maxSize){
		lruCache=new LruCache<String, Bitmap>(maxSize){
			//此方法要返回每个缓存对象的大小
			@Override
			protected int sizeOf(String key, Bitmap value) {
				// TODO Auto-generated method stub
				return value.getByteCount();
			}
		};
	}
	/**将数据放到缓存中*/
	public static void  putMemoryLruCache(String key,Bitmap bitMap){
		if(lruCache!=null){
		lruCache.put(key,bitMap);
		Log.i("TAG", "putMemoryLruCache");
		}
	}
	/**从缓存中取数据*/
	public static Bitmap getBitmapFromMemoryLruCache(String key){
		if(lruCache!=null){
		return lruCache.get(key);
		}
		return null;
	}
	public static void loadBitmapAsync(Context context,ImageView imageView,String path,int reqWidth,int reqHeight){
		//1.判定内存时候有数据,内存有数据则直接显示?
		Bitmap bitMap=getBitmapFromMemoryLruCache(path);
	    if(bitMap!=null){
	    imageView.setImageBitmap(bitMap);
	    return;
	    }
	    //2.内存没有则启异步任务加载数据,何时启动新的异步任务?
		//a)imageview上没有绑定的异步任务
		//b)imageView上有异步任务,但此异步任务正在加载的数据不是我们需要的数据
		if(cancelBitmapWorkerTask(path,imageView)){
		//构建异步任务
		BitmapWorkerTask task=
		new BitmapWorkerTask(imageView);
		//构建一个AsyncDrawable对象,并绑定异步任务
		Bitmap defaultBitmap=
		BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_launcher);
		AsyncDrawable drawable=
		new AsyncDrawable(context,
		defaultBitmap,//默认图片
		task);
		
		//imageview绑定drawable对象
		imageView.setImageDrawable(drawable);
		
		task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,path,reqWidth,reqHeight);
		}
		
	}
	/**用于检测是否要创建新的异步对象*/
	static boolean cancelBitmapWorkerTask(String reqPath,ImageView imageView){
		//1.检测imageview上有没有绑定的异步任务
		BitmapWorkerTask task=
		getBitmapWorkerTask(imageView);
		//2.检测异步中加载的数据是否是我们需要的数据
		if(task!=null){
			if(!task.loadingPath.equals(reqPath)){
				task.cancel(true);//退出原有异步任务
				return true;//开启新的异步任务
			}else{
				return false;//不需要重新开启异步任务
			}
		}
		return true;
	}
	/**检测imageview上有没有绑定的异步任务*/
	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView){
		Drawable drawable=imageView.getDrawable();
		if(drawable instanceof AsyncDrawable){
			AsyncDrawable aDrawable=
			(AsyncDrawable)drawable;
			return aDrawable.getBitmapWorkerTask();
		}
		return null;
	}
	static class BitmapWorkerTask extends AsyncTask<Object, Integer, Bitmap> {
		private WeakReference<ImageView> weakReference;
		public BitmapWorkerTask(ImageView imageView) {
			this.weakReference = new WeakReference<ImageView>(imageView);
		}
		private String loadingPath;
		@Override
		protected Bitmap doInBackground(Object... params) {
			try{Thread.sleep(100);}catch(Exception e){};
			loadingPath=(String)params[0];
			//加载Bitmap对象
			Bitmap bitMap=BitmapUtils.
			decodeSampledBitmapFromResource(
					loadingPath,
			(Integer)params[1],
			(Integer)params[2]);
			//缓存bitmap对象
			putMemoryLruCache(loadingPath, bitMap);
			return bitMap;
		}
		@Override
		protected void onPostExecute(Bitmap result) {
			if(isCancelled())return;
			if (weakReference != null && result != null) {
				final ImageView imageView = weakReference.get();
				BitmapWorkerTask task=getBitmapWorkerTask(imageView);
				if (task==this&&imageView != null) {
					imageView.setImageBitmap(result);
				}
			}
		}
	}
	/**构建此类的目的是希望此对象与一个异步任务对象绑定在一起,
	 * 然后通过此对象的异步任务加载图片*/
	static class AsyncDrawable extends BitmapDrawable {
		  private WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
		  public AsyncDrawable(Context context,Bitmap bitMap,BitmapWorkerTask task) {
			  super(context.getResources(), bitMap);
			  this.bitmapWorkerTaskReference =new WeakReference<ImageLoaderUtils.BitmapWorkerTask>(task);
		  }
		  /*public void setBitmapWorkerTaskReference(BitmapWorkerTask task) {
			this.bitmapWorkerTaskReference =new WeakReference<ImageLoaderUtils.BitmapWorkerTask>(task);
		  }*/
		  /**通过此方法获得一个BitmapWorkerTask*/
		  public BitmapWorkerTask getBitmapWorkerTask() {
			  return bitmapWorkerTaskReference.get();
		  }
	}
		
		
}

main:

public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//创建一个缓存LruCache对象
		ActivityManager aManager=(ActivityManager)
		getSystemService(Context.ACTIVITY_SERVICE);
		int memorySize=aManager.getMemoryClass();
		Log.i("TAG", "memorySize="+memorySize);
		int lruCacheSize=memorySize*1024*1024/8;
		ImageLoaderUtils.buildMemoryLruCache(lruCacheSize);
		
		//初始化数据
		AnimalProvider aProvider=new AnimalProvider();
		
		//初始化listview
		ListView lsv=(ListView) findViewById(R.id.lsvId);
		
		AnimalAdapter adapter=new AnimalAdapter(this,
		R.layout.list_item_02,aProvider.getAnimals());
		
		lsv.setAdapter(adapter);
	}
}





1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值