应用的缓存文件夹的获取
应用缓存文件夹是系统分配给每个应用的固定的缓存存储位置,该位置在应用卸载/清理数据时删除其中的内容
//获取缓存文件夹 /sdcard/Android/data/应用包名/cache
localCachePath = context.getApplicationContext().getExternalCacheDir().toString();
本地图片缩略图二级缓存
思路:对于要显示的一张图片的缩略图,可以在第一次没有缩略图时生成缩略图并分别保存到缓存文件夹下以及内存中,在下次需要显示时可以先去检测内
存是否有记录,有则直接显示,没有则取磁盘的缓存文件夹下加载(加载成功显示时再保存到内存中),如果本地缓存没有则从原图上创建缩略图同时保存到
本地缓存以及内存中。
内存缓存的管理
//内存缓存类
private LruCache<String, Bitmap> caches;
//初始化内存缓存对象
caches = new LruCache<String, Bitmap>(size) {
@Override
protected int sizeOf(String key, Bitmap value) {
//处理缓存的图片的大小计算
return value.getRowBytes() * value.getHeight();
}
};
加载的关键:
public void showImage(String path, ImageView iv) {
//针对该路径检测内存中是否有对应的缩略图
if (caches.get(path) != null) {
iv.setImageBitmap(caches.get(path));
} else {
//没有缩略图,检测本地是否有缩略图
String thumbPath = getLocalCachePath(path);
File f = new File(thumbPath);
if (f.exists()) {
//有缩略图,从本地缓存文件夹中加载缩略图
Bitmap thumb = BitmapUtil.getBitmap(thumbPath, 100, 100);
if (null != thumb) {
//保存到内存中,方便下次可以从内存中快速的读取
caches.put(path, thumb);
//显示
iv.setImageBitmap(thumb);
} else {
//显示默认图标
}
} else {
//生成缩略图
executorService.execute(new CreateThumbRunnable(path,iv,100,100));
}
}
}
class CreateThumbRunnable extends Handler implements Runnable {
private String path;
private int width;
private int height;
private ImageView iv;
public CreateThumbRunnable(String path,ImageView iv, int width, int height) {
this.iv = iv;
this.path = path;
this.width = width;
this.height = height;
}
@Override
public void run() {
//从原图上生成缩略图
Bitmap thumb = BitmapUtil.getBitmap(path, width, height);
if (thumb != null) {
//保存到本地缓存文件夹中
String thumbPath = getLocalCachePath(path);
BitmapUtil.saveBitmap(thumb, thumbPath);
//保存到内存中
caches.put(path, thumb);
//显示
obtainMessage(1, thumb).sendToTarget();
} else {
sendEmptyMessage(0);
}
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
//生成成功
Bitmap b = (Bitmap) msg.obj;
iv.setImageBitmap(b);
break;
case 0:
//生成失败,显示默认图标
break;
}
}
}
生成视频缩略图
Bitmap thumb = null;
//在api10以上
if (Build.VERSION.SDK_INT >= 10) {
MediaMetadataRetriever mr = new MediaMetadataRetriever();
try {
//设置视频源
mr.setDataSource(f.getPath());
//获取视频上的某一帧图像
thumb = mr.getFrameAtTime();
} catch (Exception e) {
thumb = ThumbnailUtils.createVideoThumbnail(f.getPath(),MediaStore.Images.Thumbnails.MICRO_KIND);
} finally {
//释放资源
mr.release();
}
} else {
thumb = ThumbnailUtils.createVideoThumbnail(f.getPath(),MediaStore.Images.Thumbnails.MICRO_KIND);
}
ViewPager的适配器封装
默认是需要显示某个页面时初始显示的视图,如果需要显示的页面非常多,那么在切换时会出现不断的初始化和销毁,所以可以定义集合记录曾经用过的视
图,在下一次需要初始化时直接用缓存集合中取出显示即可
public abstract class XPagerAdapter<T> extends PagerAdapter {
//显示的视图
private Map<Integer, View> showViews;
//缓存队列
private LinkedList<View> caches;
protected List<T> list;
protected Context context;
public XPagerAdapter(Context context) {
this.context = context;
showViews = new HashMap<Integer, View>();
caches = new LinkedList<View>();
}
@Override
public int getCount() {
return null == list ? 0 : list.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
//获取要移除的视图(之前显示过的)
View v = showViews.get(position);
container.removeView(v);
//将移除的视图对象记录起来
caches.addLast(v);
showViews.remove(position);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//给数据配置显示视图
View itemView;
//如果缓存区中有视图,可以直接拿来显示
if (!caches.isEmpty()) {
itemView = caches.removeFirst();
} else {
itemView = createView();
}
//获取要显示的数据
T t = list.get(position);
//将数据和显示视图绑定
bindView(itemView,t);
itemView.setTag(position);
container.addView(itemView);
//将当前显示的视图用一位置记录起来
showViews.put(position, itemView);
return itemView;
}
/**
* 创建每个页面需要的视图
* @return
*/
protected abstract View createView();
/**
* 绑定视图
* @param itemView
* @param item
*/
protected abstract void bindView(View itemView,T item);
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
notifyDataSetChanged();
}
}
使用
public class ImagePagerAdapter extends XPagerAdapter<String> {
//屏幕宽度和高度
private int screenWidth,screenHeight;
public ImagePagerAdapter(Context context) {
super(context);
screenWidth = context.getResources().getDisplayMetrics().widthPixels;
screenHeight = context.getResources().getDisplayMetrics().heightPixels;
}
@Override
protected View createView() {
ImageView iv = new ImageView(context);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
iv.setLayoutParams(lp);
return iv;
}
@Override
protected void bindView(View itemView, String item) {
ImageView iv = (ImageView) itemView;
//加载缩略图来显示
XImageLoader.getInstance(context).showImage(item,iv,screenWidth,screenHeight,true);
}
}
屏幕宽高的获取
//屏幕宽方向的像素个数(屏幕宽度)
screenWidth = context.getResources().getDisplayMetrics().widthPixels;
//屏幕高度
screenHeight = context.getResources().getDisplayMetrics().heightPixels;