关于缓存你了解多少(一)

上一张图爽一下先,哈哈

上主题三级缓存,关于数据缓存问题经常用到,尤其是加载网络图片 仅仅是线程池+网络框架有时候并不能满足我们的需求,这时候我们考虑三级缓存,即从磁盘中读写数据, 访问网络图片的框架有很多,个人喜好觉得volley非常的好用可能是自己在这个上面研究过一段时间吧,

废话不多说了 直接上demo,明天签到项目中吧,

DiskLruCache不了解的先查一下


/**
* 图片缓存管理类 获取ImageLoader对象
*/
public class ImageCacheManager {

public static String TAG = ImageCacheManager.class.getSimpleName();

// 获取图片缓存类对象
public static ImageCache mImageCache = new ImageCacheUtil();
// 获取ImageLoader对象
public static ImageLoader mImageLoader = new ImageLoader(VolleyRequestQueueManager.mRequestQueue, mImageCache);

/**
* 获取ImageListener
*
* @param view
* @param defaultImage
* @param errorImage
* @return
*/
public static ImageListener getImageListener(final ImageView view, final Bitmap defaultImage, final Bitmap errorImage) {

return new ImageListener() {

@Override
public void onErrorResponse(VolleyError error) {
// 回调失败
if (errorImage != null) {
view.setImageBitmap(errorImage);
}
}

@Override
public void onResponse(ImageContainer response, boolean isImmediate) {
// 回调成功
if (response.getBitmap() != null) {
view.setImageBitmap(response.getBitmap());
} else if (defaultImage != null) {
view.setImageBitmap(defaultImage);
}
}
};

}

/**
* 提供给外部调用方法
*
* @param url
* @param view
* @param defaultImage
* @param errorImage
*/
public static void loadImage(String url, ImageView view, Bitmap defaultImage, Bitmap errorImage) {
mImageLoader.get(url, ImageCacheManager.getImageListener(view, defaultImage, errorImage), 0, 0);
}

/**
* 提供给外部调用方法
*
* @param url
* @param view
* @param defaultImage
* @param errorImage
*/
public static void loadImage(String url, ImageView view, Bitmap defaultImage, Bitmap errorImage, int maxWidth, int maxHeight) {
mImageLoader.get(url, ImageCacheManager.getImageListener(view, defaultImage, errorImage), maxWidth, maxHeight);
}
}

----------------------------------------------

package com.example.mydemo;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import libcore.io.DiskLruCache;
import libcore.io.DiskLruCache.Snapshot;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.support.v4.util.LruCache;
import android.util.Log;

import com.android.volley.toolbox.ImageLoader.ImageCache;
import com.example.mydemo.utils.MD5Utils;

/**
* 图片缓存帮助类
* 包含内存缓存LruCache和磁盘缓存DiskLruCache
* 即二级缓存
*/
public class ImageCacheUtil implements ImageCache {

public String TAG=ImageCacheUtil.this.getClass().getSimpleName();

//缓存类
public static LruCache<String, Bitmap> mLruCache;
public static DiskLruCache mDiskLruCache;

//磁盘缓存大小
public static final int DISKMAXSIZE = 10 * 1024 * 1024;

public ImageCacheUtil() {
// 获取应用可占内存的1/8作为缓存
int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8);
// 实例化LruCaceh对象
mLruCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
try {
// 获取DiskLruCahce对象
mDiskLruCache = DiskLruCache.open(getDiskCacheDir(MyApplication.newInstance(), "Rabbit"), getAppVersion(MyApplication.newInstance()), 1, DISKMAXSIZE);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 从缓存(内存缓存,磁盘缓存)中获取Bitmap
*/
@Override
public Bitmap getBitmap(String url) {
if (mLruCache.get(url) != null) {
// 从LruCache缓存中取
Log.i(TAG,"从LruCahce获取");
return mLruCache.get(url);
} else {
String key = MD5Utils.md5(url);
try {
if (mDiskLruCache.get(key) != null) {
// 从DiskLruCahce取
Snapshot snapshot = mDiskLruCache.get(key);
Bitmap bitmap = null;
if (snapshot != null) {
bitmap = BitmapFactory.decodeStream(snapshot.getInputStream(0));
// 存入LruCache缓存
mLruCache.put(url, bitmap);
Log.i(TAG,"从DiskLruCahce获取");
}
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

/**
* 存入缓存(内存缓存,磁盘缓存)
*/
@Override
public void putBitmap(String url, Bitmap bitmap) {
// 存入LruCache缓存
mLruCache.put(url, bitmap);
// 判断是否存在DiskLruCache缓存,若没有存入
String key = MD5Utils.md5(url);
try {
if (mDiskLruCache.get(key) == null) {
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
if (bitmap.compress(CompressFormat.JPEG, 100, outputStream)) {
editor.commit();
} else {
editor.abort();
}
}
mDiskLruCache.flush();
}
} catch (IOException e) {
e.printStackTrace();
}

}

/**
* 该方法会判断当前sd卡是否存在,然后选择缓存地址
*
* @param context
* @param uniqueName
* @return
*/
public static File getDiskCacheDir(Context context, String uniqueName) {
String cachePath=null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {

cachePath = context.getExternalCacheDir().getPath();
} else {
cachePath = context.getCacheDir().getPath();
}
return new File(cachePath + File.separator + uniqueName);
}

/**
* 获取应用版本号
*
* @param context
* @return
*/
public int getAppVersion(Context context) {
try {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return info.versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return 1;
}

}

--------------------------------------------------------------

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnClickListener {

private ImageView image;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

image = (ImageView) findViewById(R.id.image);
image.setOnClickListener(this);
}

String url = "http://img5.duitang.com/uploads/item/201404/13/20140413232106_tGXkT.jpeg";

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.image:

ImageCacheManager.loadImage(url, image,
getBitmapFromRes(R.drawable.ic_launcher),
getBitmapFromRes(R.drawable.ic_launcher));
break;

default:
break;
}
}

public Bitmap getBitmapFromRes(int resId) {
Resources res = this.getResources();
return BitmapFactory.decodeResource(res, resId);

}
}

-----------------------------------------------------------------

package com.example.mydemo;

import android.app.Application;

public class MyApplication extends Application {

public static String TAG;
private static MyApplication myApplication;
public static MyApplication newInstance(){
return myApplication;
}

@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();

TAG=this.getClass().getSimpleName();
myApplication = this;
}

------------------------------------------------------

package com.example.mydemo;


import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

public class VolleyRequestQueueManager {

// 获取请求队列类
public static RequestQueue mRequestQueue = Volley.newRequestQueue(MyApplication.newInstance());

//添加任务进任务队列
public static void addRequest(Request<?> request, Object tag) {
if (tag != null) {
request.setTag(tag);
}
mRequestQueue.add(request);
}

//取消任务
public static void cancelRequest(Object tag){
mRequestQueue.cancelAll(tag);
}

}

-----------------------------------------------------------

送个MD5工具类

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {
/**
* 使用md5的算法进行加密
*/
public static String md5(String plainText) {
byte[] secretBytes = null;
try {
secretBytes = MessageDigest.getInstance("md5").digest(
plainText.getBytes());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有md5这个算法!");
}
String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
// 如果生成数字未满32位,需要前面补0
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
}

---------------------------------------------------------------------

DiskLruCache篇幅太长 自己copy然后简报

总结:注意小细节,网络读写权限,Application清单文件。。。等等,

关于应用移除图片是否跟着消失还没来得看,先做个标记吧,

关于高德地图的自动定位,逆地理编码以及导航做完了 明天再补上,

感觉定位文档有点坑啊,

另附:关于go的学习不能拉下啊,提醒一下自己吧,

 

 

完整DEMO下载:

http://download.csdn.net/detail/onebelowzero2012/9342369,加群521039620,欢迎交流!

 

附参考:尊重原作者

http://blog.csdn.net/jie1991liu/article/details/46926421

http://blog.saymagic.cn/2015/01/30/android-pic-three-cache.html

http://www.w2bc.com/Article/42376

http://www.tuicool.com/articles/MR3yAr

http://blog.csdn.net/lwyygydx/article/details/40401211

 

posted @ 2015-12-10 02:07  一座城池2012  阅读(804)  评论(0编辑  收藏  举报