android Caching Bitmaps学习

参考链接:

Displaying Bitmaps Efficiently

Caching Bitmaps 翻译

先吐槽一下:google 给示例中都有错误的地方,国内翻译的也不去掉错误.太坑.

谷歌官方Download
the sample

也可参照guolin的文章,

经过一番学习,初步实践完成.贴出来,备用.

package com.akm.testlrucache;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.DisplayMetrics;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

public class BitmapCacheUtil {
	private Context context;
	private int screenWidth = 0;
	private int screenHeight = 0;
	private final int TITLE_HEIGHT = 48;
	private ImageView imageView;
	private int resid;
	private LruCache<String, Bitmap> mMemoryCache;
	private BitmapWorkerTask  task ;
	public BitmapCacheUtil(Context context , ImageView imageView,int resid) {
		this.context = context;
		this.imageView = imageView;
		this.resid =resid; 

		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int cacheSize = maxMemory / 8;
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				return bitmap.getByteCount();
			}
		};
		loadBitmap();

	}

	public void loadBitmap() {   

		Bitmap bitmap = getBitmapFromMemoryCache(String.valueOf(resid));
		if (bitmap==null) {
			// mImageView.setImageResource(R.drawable.image_placeholder);
			task = new BitmapWorkerTask();
			task.execute(resid);
		}else{
			imageView.setImageBitmap(bitmap);
		}
	}  

	private Bitmap getBitmapFromMemoryCache(String key) {
		return mMemoryCache.get(key);
	}  

	private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
		if (getBitmapFromMemoryCache(key) == null) {
			mMemoryCache.put(key, bitmap);
		}
	}  

	protected void setImageView() {
		Bitmap bitmap = getBitmapFromMemoryCache(String.valueOf(resid));
		if (bitmap != null) {
			imageView.setImageBitmap(bitmap);
		} else {
			imageView.setImageResource(R.drawable.ic_launcher);
		}
	}  

	class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {   

		@Override
		protected Bitmap doInBackground(Integer... params) {
			final Bitmap bitmap = decodeSampledBitmapFromResource(context.getResources(), params[0], getScreenWidth(context), getScreenHeight(context));
			addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
			return bitmap;
		}  

		@Override
		protected void onPostExecute(Bitmap bitmap) {
			super.onPostExecute(bitmap);
			if (bitmap != null) {
				imageView.setImageBitmap(bitmap);
			}
		}   

	}  

	public Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
			int reqWidth, int reqHeight) {

		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(res, resId, options);

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

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeResource(res, resId, options);
	}
	public int calculateInSampleSize(
			BitmapFactory.Options options, int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		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 void cancelTask() {
		if (task != null) {
			task.cancel(false);
		}
	}  

	@SuppressWarnings("deprecation")
	public int getScreenWidth(Context context) {
		if (screenWidth != 0) {
			return screenWidth;
		}
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		screenWidth = wm.getDefaultDisplay().getWidth();
		return screenWidth;
	}

	@SuppressWarnings("deprecation")
	public int getScreenHeight(Context context) {
		if (screenHeight != 0) {
			return screenHeight;
		}
		int top = 0;
		if (context instanceof Activity) {
			top = ((Activity) context).getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
			if (top == 0) {
				top = (int) (TITLE_HEIGHT * getScreenDensity(context));
			}
		}
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		screenHeight = wm.getDefaultDisplay().getHeight() - top;
		return screenHeight;
	}
	public float getScreenDensity(Context context) {
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics metric = new DisplayMetrics();
		wm.getDefaultDisplay().getMetrics(metric);
		return metric.density;
	}

	public float getScreenDensityDpi(Context context) {
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics metric = new DisplayMetrics();
		wm.getDefaultDisplay().getMetrics(metric);
		return metric.densityDpi;
	}

}
时间: 2024-11-05 12:19:48

android Caching Bitmaps学习的相关文章

Android Training Caching Bitmaps 翻译

原文:http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html 图片缓存 在Android开发中,加载一个图片到界面很容易,但如果一次加载大量图片就复杂多了.在很多情况下(比如:ListView,GridView或ViewPager),能够滚动的组件需要加载的图片几乎是无限多的. 有些组件的child view在不显示时会回收,并循环使用,如果没有任何对bitmap的持久引用的话,垃圾回收器会释放你加载的

Caching Bitmaps

由于要做网络图片的显示,所以先翻译了一下官网的文档,以作备用,  地址http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html. Loading a single bitmap into your user interface (UI) is straightforward, however things get more complicated if you need to load a large

基于 Android NDK 的学习之旅----- C调用Java

http://www.cnblogs.com/luxiaofeng54/archive/2011/08/17/2142000.html 基于 Android NDK 的学习之旅----- C调用Java许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现. 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态方法. 1.主要流程 1.  新建一个测试类TestProvider.java a)       

【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)

原文网址:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/20/2147086.html 基于 Android NDK 的学习之旅-----数据传输二(引用数据类型)(附源码) 基于 Android NDK 的学习之旅-----数据传输(引用数据类型) 接着上篇文章继续讲.主要关于引用类型的数据传输,本文将介绍字符串传输和自定义对象的传输. 1.主要流程 1.  String 字符串传输 a)         上层定义一个native的方法

Android Web Service学习总结(一)

最近学习android平台调用webWebService,学习了一篇不错的博客(http://blog.csdn.net/lyq8479/article/details/6428288),可惜是2011年时的方法,而不适合现在android4.0之后的android版本,所以通过一番学习和研究,总结如下. web Service简介 通俗的理解:通过使用WebService,我们能够像调用本地方法一样去调用远程服务器上的方法.我们并不需要关心远程的那个方法是Java写的,还是PHP或C#写的:我

Android ARM指令学习

在逆向分析Android APK的时候,往往需要分析它的.so文件.这个.so文件就是Linux的动态链接库,只不过是在ARM-cpu下编译的.所以学习Android下的ARM指令很重要.目前,市面上的ARM-cpu基本都支持一种叫做THUMB的指令集模式.这个THUMB指令集可以看作是ARM指令集的子集,只不过ARM指令集为32bit,THUMB指令集为16bit.之所以要使用这个THUMB指令集,主要是为了提升代码密度.具体信息大家可以google. 下面介绍如何简单修改.so文件. 首先,

Android热修复学习之旅——HotFix完全解析

在上一篇博客Android热修复学习之旅开篇--热修复概述中,简单介绍了各个热修复框架的原理,本篇博客我将详细分析QQ空间热修复方案. Android dex分包原理介绍 QQ空间热修复方案基于Android dex分包基础之上,简单概述android dex分包的原理就是:就是把多个dex文件塞入到app的classloader之中,但是android dex拆包方案中的类是没有重复的,如果classes.dex和classes1.dex中有重复的类,当classes.dex和classes1

android开发的学习路线

android开发的学习路线 第一阶段:Java面向对象编程1.Java基本数据类型与表达 式,分支循环. 2.String和StringBuffer的使用.正则表达式. 3.面向对象的抽象,封装,继承,多态,类与对象,对象初始化和回 收:构造函数.this关键字.方法和方法的参数传递过程.static关键字.内部类,Java的垃极回收机制,Javadoc介绍. 4.对象实例化 过程.方法的覆盖.final关键字.抽象类.接口.继承的优点和缺点剖析:对象的多态性:子类和父类之间的转换.抽象类和接

Android Afinal框架学习(一) FinalDb 数据库操作

框架地址:https://github.com/yangfuhai/afinal 对应源码: net.tsz.afinal.annotation.sqlite.* net.tsz.afinal.db.sqlite.* net.tsz.afinal.db.table.* net.tsz.afinal.utils.ClassUtils.net.tsz.afinal.utils.FieldUtils FinalDb 建库 FinalDb db = FinalDb.create(context, "my