android三级缓存
目前缓存机制使用大致流程是,当App需要加载某一张图片时,先去手机内存中去找该图片,如果有,那么直接显示,如果无,则去手机sd卡或者手机外部存储中找该图片,如果有,那么直接显示,如果无,那么此时才去网络下载该图片。这种机制常称为三级缓存策略。
三级缓存代码:
主类代码:
isLurCache ilc = new isLurCache();
TextView getimg;
ImageView img;
String str = "http://upload-images.jianshu.io/upload_images/6416344-278e4f9266d79331.jpg";
//获取内存
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
getimg = findViewById(R.id.getimg);
img = findViewById(R.id.img);
//切割获取图片名称
final String[] split = str.split("/");
//设置监听
getimg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("点击###","点了一下");
//如果内存有,就从内存去拿
if(Share.ilc.getLruCache(split[4])!=null){
Log.i("内存###","内存判断");
Bitmap bitmap = Share.ilc.getLruCache(split[4]);
img.setImageBitmap(bitmap);
//内存没有就从本地去拿
}else if(showLocal(split[4])!=null){
Log.i("本地###","本地判断");
Bitmap bitmap = showLocal(split[4]);
img.setImageBitmap(bitmap);
Log.i("内存获取###","内存设置图片");
//本地没有就从网上获取 然后存入到内存
}else{
//开启网络读取,给线程
Log.i("线程###","开启线程");
new HttpThreadUtils(str).start();
}
}
});
}
在一个监听中,去判断每个位置是否存在该数据
创建内存
public class isLurCache {
LruCache<String, Bitmap> lruCache;
public isLurCache() {
int max = (int)Runtime.getRuntime().maxMemory();
lruCache = new LruCache<String,Bitmap>(max / 8){
/**
* 获取图片长度
* @param key
* @param value
* @return
*/
@Override
protected int sizeOf(String key, Bitmap value) {
return super.sizeOf(key, value);
}
};
}
/**
* 判断图片是否存在
* @param name
* @return
*/
public Bitmap getLruCache(String name){
if(lruCache.get(name)!=null){
return lruCache.get(name);
}
return null;
}
/**
* 存数据
* @param key
* @param v
*/
public void setLruCache(String key,Bitmap v){
Log.i("key###",key);
Log.i("bitmap###",v+"");
lruCache.put(key,v);
}
}
创建网络访问工具类
public class HttpThreadUtils extends Thread{
String url;
isLurCache ilc = new isLurCache();
public HttpThreadUtils(String url) {
this.url = url;
}
@Override
public void run() {
try {
Log.i("进入线程###","进入线程");
URL u = new URL(url);
HttpURLConnection connection = (HttpURLConnection)u.openConnection();
Log.i("连接###","已连接1");
//设置访问方式
connection.setRequestMethod("GET");
Log.i("连接###","已连接2");
//建立连接
connection.connect();
Log.i("连接###","已连接3");
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
if(connection.getResponseCode() == 200){
Log.i("进入连接###","连接");
InputStream is = connection.getInputStream();
ByteArrayOutputStream os = new ByteArrayOutputStream();
//获取本地地址
File file = Environment.getExternalStorageDirectory();
String[] split = url.split("/");
FileOutputStream outputStream = new FileOutputStream(new File(file, split[4]));
byte[] b = new byte[1024];
int len = -1;
while((len = is.read(b))!=-1){
// outputStream.write(b,0,len);
os.write(b,0,len);
}
os.close();
is.close();
outputStream.close();
Log.i("线程###","读完了");
Bitmap bitmap = getBitmap(os.toByteArray());
setBitmap(bitmap);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public Bitmap getBitmap(byte[] bs){
Log.i("获取图片###","线程设置图片");
Bitmap bitmap = BitmapFactory.decodeByteArray(bs,0,bs.length);
return bitmap;
}
/**
* 设置给内存
* @param bitmap
*/
public void setBitmap(Bitmap bitmap){
String[] split = url.split("/");
Share.ilc.setLruCache(split[4],bitmap);
Log.i("设置内存###","内存");
}
}
查看本地方法
/**
* 查看本地是否存在
*/
public Bitmap showLocal(String name){
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File file = Environment.getExternalStorageDirectory();
File file1 = new File(file, name);
if(file1.exists()){
Log.i("本地###","本地");
Bitmap bitmap = BitmapFactory.decodeFile(file1.getAbsolutePath());
return bitmap;
}
}
return null;
}
在访问内存时,必须是同一个内存地址,不然回报空导致拿不到内存的数据,所以需要共用一个内存类:
public class Share {
public static isLurCache ilc = new isLurCache();
}
效果图:在这里插入图片描述
没有点击时
##
点击之后
附加一条:可以去简书关注一下这位小姐姐,文章都很好。 ID:诗音姑娘