listview优化
ListView优化,ListView内存优化
ListView异步加载缓存图片
1、复用convertView 2、缓存findViewById(),static viewHolder 3、软引用、弱引用 用LruCache替换 4、图片缩放 |
1、复用convertView |
2、ViewHolder缓存查找到的组件的引用,防止多次查找,浪费内存和耗时 private static class ViewHolder {
private TextView tv;
private ImageView iv;
}...... View view = null;
ViewHolder viewHolder = null;
if (convertView != null && convertView instanceof LinearLayout) {
System.out.println("复用以前的convertView:" + position);
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}else {
System.out.println("新创建View:" + position);
view = View.inflate(getApplicationContext(), R.layout.bitmap_list, null);
viewHolder = new ViewHolder();
viewHolder.tv = (TextView) view.findViewById(R.id.tv);
viewHolder.iv = (ImageView) view.findViewById(R.id.iv);
view.setTag(viewHolder);
}
|
3、软引用和弱引用 // TODO 1:软引用、虚引用
// SoftReference<ImageView> softReferenceBitmap = new SoftReference<ImageView>(iv);
WeakReference<Bitmap> softReferenceBitmap = new WeakReference<Bitmap>(bitmap);
bitmap.recycle();
bitmap = null;...... WeakReference<Bitmap> softReferenceBitmap = softReferenceImages.get(position);
Bitmap refBitmap = softReferenceBitmap.get();
if (refBitmap == null) {
// System.gc();
System.out.println("被GC回收:" + position);
refBitmap = scaleBitmap(imagesIds[position]);
}
|
4、图片缩放 /**
* //TODO 2:图片缩放
* @param resId 要缩放的图片的id
* @return 缩放后的图片的bitmap
*/
@SuppressLint("NewApi")
// api13
private Bitmap scaleBitmap(int resId) {
Options opts = new Options();
opts.inJustDecodeBounds = true;// 不是真正的去解析图片,而是解析图片的头
BitmapFactory.decodeResource(getResources(), resId, opts);
int outWidth = opts.outWidth;
int outHeight = opts.outHeight;
System.out.println("图片宽度:" + outWidth);
System.out.println("图片高度:" + outHeight);
// 获取屏幕尺寸
Display display = wm.getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
int window_width = screenSize.x;
int window_height = screenSize.y;
System.out.println("屏幕宽度:" + window_width);
System.out.println("屏幕高度:" + window_height);
int scale = 1;
int scaleX = outWidth / window_width;
int scaleY = outHeight / window_height;
if (scaleX < scaleY) {// 按照最大的缩放
scale = scaleY;
} else if (scaleX >= scaleY) {
scale = scaleX;
}
opts.inSampleSize = scale;// 缩放比例,如果大于0,缩放比例为x和y轴各缩放1/scale,小于0,原图
System.out.println("缩放比例:" + scale);
opts.inJustDecodeBounds = false;// 重新设置为解析全图
return BitmapFactory.decodeResource(getResources(), resId, opts);
}
|
全部核心代码: package cn.zengfansheng.softreferencetest;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
private ListView lv;
private int[] imagesIds;
// private ArrayList<SoftReference<ImageView>> softReferenceImages;
private ArrayList<WeakReference<Bitmap>> softReferenceImages;
private WindowManager wm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
initData();
lv = (ListView) this.findViewById(R.id.lv);
MyAdapter adapter = new MyAdapter();
lv.setAdapter(adapter);
// VMRuntime
}
@SuppressLint("NewApi")
public void initData() {
imagesIds = LoadRes.loadResId();
// softReferenceImages = new ArrayList<SoftReference<ImageView>>();
softReferenceImages = new ArrayList<WeakReference<Bitmap>>();
for (int i : imagesIds) {
Bitmap bitmap = scaleBitmap(i);
// TODO 1:软引用、虚引用
// SoftReference<ImageView> softReferenceBitmap = new SoftReference<ImageView>(iv);
WeakReference<Bitmap> softReferenceBitmap = new WeakReference<Bitmap>(bitmap);
bitmap.recycle();
bitmap = null;
System.gc();
softReferenceImages.add(softReferenceBitmap);
}
}
/**
* //TODO 2:图片缩放
* @param resId 要缩放的图片的id
* @return 缩放后的图片的bitmap
*/
@SuppressLint("NewApi")
// api13
private Bitmap scaleBitmap(int resId) {
Options opts = new Options();
opts.inJustDecodeBounds = true;// 不是真正的去解析图片,而是解析图片的头
BitmapFactory.decodeResource(getResources(), resId, opts);
int outWidth = opts.outWidth;
int outHeight = opts.outHeight;
System.out.println("图片宽度:" + outWidth);
System.out.println("图片高度:" + outHeight);
// 获取屏幕尺寸
Display display = wm.getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
int window_width = screenSize.x;
int window_height = screenSize.y;
System.out.println("屏幕宽度:" + window_width);
System.out.println("屏幕高度:" + window_height);
int scale = 1;
int scaleX = outWidth / window_width;
int scaleY = outHeight / window_height;
if (scaleX < scaleY) {// 按照最大的缩放
scale = scaleY;
} else if (scaleX >= scaleY) {
scale = scaleX;
}
opts.inSampleSize = scale;// 缩放比例,如果大于0,缩放比例为x和y轴各缩放1/scale,小于0,原图
System.out.println("缩放比例:" + scale);
opts.inJustDecodeBounds = false;// 重新设置为解析全图
return BitmapFactory.decodeResource(getResources(), resId, opts);
}
// TODO 3: ViewHolder,findViewByid() 查找id的优化
private static class ViewHolder {
private TextView tv;
private ImageView iv;
}
// TODO :适配器
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return softReferenceImages.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO 4:使用convertView缓存
View view = null;
ViewHolder viewHolder = null;
if (convertView != null && convertView instanceof LinearLayout) {
System.out.println("复用以前的convertView:" + position);
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}else {
System.out.println("新创建View:" + position);
view = View.inflate(getApplicationContext(), R.layout.bitmap_list, null);
viewHolder = new ViewHolder();
viewHolder.tv = (TextView) view.findViewById(R.id.tv);
viewHolder.iv = (ImageView) view.findViewById(R.id.iv);
view.setTag(viewHolder);
}
//SoftReference<ImageView> softReferenceBitmap = softReferenceImages.get(position);
WeakReference<Bitmap> softReferenceBitmap = softReferenceImages.get(position);
Bitmap refBitmap = softReferenceBitmap.get();
if (refBitmap == null) {
// System.gc();
System.out.println("被GC回收:" + position);
refBitmap = scaleBitmap(imagesIds[position]);
}
viewHolder.tv.setText("图片名称:1000" + Math.random() * 100);
viewHolder.iv.setImageBitmap(refBitmap);
return view;
}
}
} |