Skip to content

Instantly share code, notes, and snippets.

@easternHong
Created October 21, 2014 11:15
Show Gist options
  • Save easternHong/2a054b82605cb9d264eb to your computer and use it in GitHub Desktop.
Save easternHong/2a054b82605cb9d264eb to your computer and use it in GitHub Desktop.
使用IMAGE_CACHE,大幅度提升ListView GridView性能
package com.hunt.listviewdemo;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import cn.trinea.android.common.entity.CacheObject;
import cn.trinea.android.common.entity.FailedReason;
import cn.trinea.android.common.service.impl.ImageCache;
import cn.trinea.android.common.service.impl.ImageCache.CompressListener;
import cn.trinea.android.common.service.impl.ImageMemoryCache.OnImageCallbackListener;
import cn.trinea.android.common.service.impl.PreloadDataCache.OnGetDataListener;
import cn.trinea.android.common.service.impl.RemoveTypeLastUsedTimeFirst;
import cn.trinea.android.common.util.FileUtils;
import cn.trinea.android.common.util.ObjectUtils;
import com.hunt.listviewdemo.support.debug.AppLogger;
/**
* 使用ImageCache 只需要三个步骤 1.添加: <uses-permission
* android:name="android.permission.INTERNET" /> <uses-permission
* android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission
* android:name="android.permission.ACCESS_NETWORK_STATE" /> 2 a.加载ImageView //
* 获取全局访问点 public static final ImageCache IAMGE_CACHE =
* CacheManager.getImageCache(); b.静态代码块:回调。3.需要加载图片的地方使用get(imageUrl,
* imageView);
*
* @author hunt
*
*/
public class MyAdapter extends ArrayAdapter<Integer> {
private List<String> imageUrlList;
private void initImageUrlList() {
imageUrlList = new ArrayList<String>();
imageUrlList
.add("http://farm8.staticflickr.com/7409/9148527822_36fa37d7ca_z.jpg");
imageUrlList
.add("http://farm4.staticflickr.com/3755/9148527824_6c156185ea.jpg");
imageUrlList
.add("http://farm8.staticflickr.com/7318/9148527808_e804baef0b.jpg");
imageUrlList
.add("http://farm8.staticflickr.com/7318/9146300275_5fe995d123.jpg");
imageUrlList
.add("http://farm8.staticflickr.com/7288/9146300469_bd3420c75b_z.jpg");
imageUrlList
.add("http://farm8.staticflickr.com/7351/9148527976_8a4e75ae87.jpg");
imageUrlList
.add("http://farm3.staticflickr.com/2888/9148527996_f05118d7de_o.jpg");
imageUrlList
.add("http://farm3.staticflickr.com/2863/9148527892_31f9377351_o.jpg");
imageUrlList
.add("http://farm8.staticflickr.com/7310/9148528008_8e8f51997a.jpg");
imageUrlList
.add("http://farm3.staticflickr.com/2849/9148528108_dfcda19507.jpg");
imageUrlList
.add("http://farm4.staticflickr.com/3739/9148528022_e9bf03058f.jpg");
imageUrlList
.add("http://img.article.pchome.net/00/40/12/85/pic_lib/s960x639/wondergirl12s960x639.jpg");
imageUrlList
.add("http://img5.imgtn.bdimg.com/it/u=1446812229,652623722&fm=23&gp=0.jpg");
imageUrlList
.add("http://img2.duitang.com/uploads/item/201202/24/20120224223729_smMTH.thumb.600_0.jpg");
imageUrlList
.add("http://pic.pedaily.cn/resource/201301/201301271941050.jpg");
imageUrlList
.add("http://img2.duitang.com/uploads/item/201202/24/20120224223729_smMTH.thumb.600_0.jpg");
imageUrlList
.add("http://img1.imgtn.bdimg.com/it/u=522765366,4089201389&fm=23&gp=0.jpg");
imageUrlList
.add("http://wenwen.sogou.com/p/20090517/20090517143707-1281434145.jpg");
}
private LayoutInflater layoutInflater;
private int[] iamgeId = { R.drawable.img_nature2, R.drawable.img_nature3,
R.drawable.img_nature4, R.drawable.img_nature5, };
private int size = 500;
// 获取全局访问点
// public static final ImageCache IAMGE_CACHE =
// CacheManager.getImageCache();
public static final ImageCache IAMGE_CACHE = new ImageCache(128, 512);
public MyAdapter(Context mContext) {
initImageUrlList();
layoutInflater = LayoutInflater.from(mContext);
for (int i = 0; i < size; i++)
add(i);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return size;
}
@Override
public Integer getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if (convertView == null) {
// this is the content layout
convertView = layoutInflater.inflate(R.layout.item, null);
holder = new ViewHolder();
holder.appicon = (ImageView) convertView.findViewById(R.id.im);
holder.appName = (TextView) convertView.findViewById(R.id.tv);
// ....
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.appName.setText("" + position);
// String imageUrl = imageUrlList.get(position % imageUrlList.size())
// .toString();
final String imagePath = Environment.getExternalStorageDirectory()
+ "/DCIM/Flickr/2014-09-27_10-44-06.jpg";
holder.appicon.setTag(imagePath);
if (!IAMGE_CACHE.get(imagePath, holder.appicon)) {
// 设置默认图片
holder.appicon.setImageResource(R.drawable.ic_launcher);
}
return convertView;
}
private static class ViewHolder {
ImageView appicon;
TextView appName;
}
// 静态代码块,当类被载入时,调用,而且只被调用一次。
static {
// 图片加载回调接口,使用内存缓存
OnImageCallbackListener imageCallBack = new OnImageCallbackListener() {
private static final long serialVersionId = 1L;
// callback function before get image ,run on ui thread
@Override
public void onPreGet(String imageUrl, View view) {
// TODO Auto-generated method stub
AppLogger.d("pre get ");
}
// 成功加载
@Override
public void onGetSuccess(String imageUrl, Bitmap loadedImage,
View view, boolean isInCache) {
// TODO Auto-generated method stub
if (view != null && loadedImage != null
&& view instanceof ImageView) {
ImageView image = (ImageView) view;
// 获得之前设置的tag
String imageUrlTag = (String) image.getTag();
if (ObjectUtils.isEquals(imageUrl, imageUrlTag))
image.setImageBitmap(loadedImage);
// setImageScale(imageUrlTag, image);
if (!isInCache) {
image.startAnimation(getInAlphaAnimation(2000));
}
}
}
@Override
public void onGetNotInCache(String imageUrl, View view) {
// TODO Auto-generated method stub
if (view != null && view instanceof ImageView) {
((ImageView) view).setImageResource(R.drawable.ic_launcher);
}
}
@Override
public void onGetFailed(String imageUrl, Bitmap loadedImage,
View view, FailedReason failedReason) {
// TODO Auto-generated method stub
AppLogger.i(new StringBuilder(128).append("get image ")
.append(imageUrl).append(" error, failed type is: ")
.append(failedReason.getFailedType())
.append(", failed reason is: ")
.append(failedReason.getCause().getMessage())
.toString());
}
private void setImageScale(String path, ImageView image) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = getImageScale(path);
Bitmap bmBitmap = BitmapFactory.decodeFile(path, options);
image.setImageBitmap(bmBitmap);
}
public AlphaAnimation getInAlphaAnimation(long durationMillis) {
AlphaAnimation inAlphaAnimation = new AlphaAnimation(0, 1);
inAlphaAnimation.setDuration(durationMillis);
return inAlphaAnimation;
}
private int IMAGE_MAX_WIDTH = 480;
private int IMAGE_MAX_HEIGHT = 960;
private int getImageScale(String image) {
// TODO Auto-generated method stub
BitmapFactory.Options option = new BitmapFactory.Options();
// allowing the caller to query the bitmap without having to
// allocate
// the memory for its pixels.表示仅读取图片文件信息而不为图片分配内存
option.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image, option);
int scale = 1;
// 不断缩小
while (option.outWidth / scale >= IMAGE_MAX_WIDTH
|| option.outHeight / scale >= IMAGE_MAX_HEIGHT) {
scale *= 2;
}
return scale;
}
};
// 添加监听
IAMGE_CACHE.setOnImageCallbackListener(imageCallBack);
IAMGE_CACHE
.setCacheFullRemoveType(new RemoveTypeLastUsedTimeFirst<Bitmap>());
IAMGE_CACHE.setHttpReadTimeOut(10000);
IAMGE_CACHE.setOpenWaitingQueue(true);
IAMGE_CACHE.setValidTime(-1);
/********************************** SD **************************************************************/
// get data from sdcard ,加载本地已经缓存的图片
IAMGE_CACHE
.setOnGetDataListener(new OnGetDataListener<String, Bitmap>() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public CacheObject<Bitmap> onGetData(String key) {
// TODO Auto-generated method stub
AppLogger.i("path:" + key);
if (!FileUtils.isFileExist(key))
return null;
// 设置压缩
CompressListener compressListener = IAMGE_CACHE
.getCompressListener();
int compressSize = 0;
if (compressListener != null) {
compressSize = compressListener
.getCompressSize(key);
}
Bitmap bm;
if (compressSize > 1) {
BitmapFactory.Options bmo = new BitmapFactory.Options();
bmo.inSampleSize = compressSize;
bm = BitmapFactory.decodeFile(key, bmo);
} else {
bm = BitmapFactory.decodeFile(key);
}
return (bm == null ? null : new CacheObject<Bitmap>(bm));
}
});
// 有效解决OOM 问题,将图片压缩
IAMGE_CACHE.setCompressListener(new CompressListener() {
@Override
public int getCompressSize(String imagePath) {
// TODO Auto-generated method stub
if (FileUtils.isFileExist(imagePath)) {
long fileSize = FileUtils.getFileSize(imagePath) / 1000;
/**
* if the file is larger than 100k,compress to 1/(n+1) width
* and 1/(n+1)height,n=fileSize/100k
*/
if (fileSize > 500) {
return (int) (fileSize / 500) + 1;
}
}
return 1;
}
});
}
/************************************************************************************************/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment