在android中展示图片过多就会出现内存溢出,为了能够高效的展示出图片这里就用缓存来处理。
首先我们写个缓存管理类ImageManager
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView;
import com.weather.forecast.R;
//缓存管理类
public class ImageManager {
private Context context;
private LruCache<String, Bitmap> mMemoryCache;
private static ImageManager instance;
private Executor mExecutor;
private ImageManager() {
}
//单例
public static ImageManager getInstance() {
if (instance == null) {
instance = new ImageManager();
}
return instance;
}
//应用程序初始化时调用
public void init(Context context) {
this.context = context;
// 获取应用程序最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
// 设置图片缓存大小为程序最大可用内存的1/8
int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount();
}
};
mExecutor = Executors.newFixedThreadPool(3);
}
/**
*
* @param url 传入路径
* @param image 图片控件
* @param Height 图片压缩的高
* @param Width 图片压缩的宽
* @param type 用来判断是本地照片还是资源文件中的图片(1是资源文件中的图片、2是本地图片)
*/
public void loadImage(String url, ImageView image,int Height, int Width, int type) {
image.setTag(url);
Bitmap bm = mMemoryCache.get(url);
if (bm != null) {
image.setImageBitmap(bm);
} else {
//默认图
image.setImageResource(R.drawable.default_image);
//异步下载图片
BitmapWorkerTask task = new BitmapWorkerTask(image);
task.executeOnExecutor(mExecutor, url, Height, Width, type);
}
}
/**
* 异步下载图片的任务。
*
* @author guolin
*/
class BitmapWorkerTask extends AsyncTask<Object, Void, Bitmap> {
/**
* 图片的URL地址
*/
private String imageUrl;
private ImageView image;
public BitmapWorkerTask(ImageView image) {
super();
this.image = image;
}
@SuppressWarnings("unused")
@Override
protected Bitmap doInBackground(Object... params) {
Bitmap bm = null;
imageUrl = (String) params[0];
Log.i("jjf", "imageUrl:" + imageUrl);
int mHeight = (Integer) params[1];
int mWidth = (Integer) params[2];
int mType = (Integer) params[3];
if (mType == 1) {
//对资源图片进行压缩获得bitmap
bm = DateUtil.BitmapResource(context, imageUrl, mWidth, mHeight);
}else{
//对本地图片进行压缩获得bitmap
bm = DateUtil.getBitmapPath(imageUrl, mWidth, mHeight);
}
if (bm != null) {
//进行存储(键值对形式)
mMemoryCache.put(imageUrl, bm);
}
return bm;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
// 根据Tag找到相应的ImageView控件,将下载好的图片显示出来。
if (bitmap != null && imageUrl != null && image != null
&& image.getTag().equals(imageUrl)) {
image.setImageBitmap(bitmap);
}
}
}
}
程序初始化是调用如下:
public class GAPP extends Application {
@Override
public void onCreate() {
ImageManager.getInstance().init(getApplicationContext());
}
}
清单文件中注册
<application
android:name="yong.desk.weather.GAPP"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light.NoActionBar" >
<activity
图片压缩类DateUtil
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class DateUtil {
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// 源图片的高度和宽度
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// 计算出实际宽高和目标宽高的比率
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
// 一定都会大于等于目标的宽和高。
inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio;
if (heightRatio == widthRatio) {
inSampleSize = widthRatio;
}
}
return inSampleSize;
}
// 资源文件的压缩
public static Bitmap BitmapResource(Context context, String str,
int reqWidth, int reqHeight) {
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
int resId = Integer.parseInt(str);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(context.getResources(), resId, options);
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(context.getResources(), resId,
options);
}
// 本地文件的压缩
public static Bitmap getBitmapPath(String str, int Width, int Height) {
Bitmap mbitMap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.RGB_565;
BitmapFactory.decodeFile(str, options);
options.inSampleSize = calculateInSampleSize(options, Width, Height);
options.inJustDecodeBounds = false;
mbitMap = BitmapFactory.decodeFile(str, options);
return mbitMap;
}
}
工具类都已经完成了,现在就在我们要使用的地方调用方法就ok了,下面是在gridview的适配器中调用。其他地方也是同样的使用
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(
R.layout.gridview_list_background_item, null);
holder.imageName = (TextView) convertView
.findViewById(R.id.gridview_lsit_item_textView);
holder.image = (ImageView) convertView
.findViewById(R.id.gridview_lsit_item_imageView);
LayoutParams para = holder.image.getLayoutParams();
para.height = Height;
para.width = Width;
holder.image.setLayoutParams(para);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//判断本地文件路径是否为空
if (!getImagePath(position).equals("")) {
//判断本地文件是否存在
if (FileUtil.isExist(getImagePath(position))) {
//调用方法显示本地图片
ImageManager.getInstance().loadImage(
getImagePath(position), holder.image, Height, Width, 2);
} else {
//调用方法显示资源文件中的图
ImageManager.getInstance().loadImage(
Integer.toString(mImages[position]), holder.image, Height, Width, 1);
}
} else {
//调用方法显示资源文件中的图
ImageManager.getInstance().loadImage(
Integer.toString(mImages[position]), holder.image, Height, Width, 1);
}
holder.imageName.setText(list[position]);
return convertView;
}