您的位置:首页 > 移动开发 > Android开发

Android 图片三级缓存

2017-09-12 09:08 106 查看
MianActivity.class

package cn.bgs.imagethreelevelload;

import cn.bgs.imagethreelevelload.loader.Loader;

import android.os.Bundle;

import android.app.Activity;

import android.content.Context;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ImageView;

public class MainActivity extends Activity implements OnClickListener {
private Button mBtn;
private ImageView mImg;
private String imgPath="http://p3.so.qhimg.com/sdr/512_768_/t01411aad0582171873.jpg";
private  Loader load;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
load=new Loader();
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mBtn=(Button) findViewById(R.id.mBtn);
mImg=(ImageView) findViewById(R.id.mImg);

mBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {

load.load(imgPath, mImg, this);
}

}

FileUtils.class

package cn.bgs.imagethreelevelload.utils;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Bitmap.CompressFormat;

import android.graphics.BitmapFactory;

import android.os.Environment;

public class FileUtils {
private Context context;
public FileUtils(Context context){
this.context=context;
}
//判断sd卡是否存在
//Environment.getExternalStorageState()  --->获得sd卡的状态
//Environment.MEDIA_MOUNTED  --->sd卡是否存在
private boolean isSdcard(){
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
return true;
}
return false;
}
//获取文件目录的方法
private String getFile(){
String str=null;
str=context.getExternalCacheDir().getAbsolutePath();
return str;
}
//存储图片的方法
public void saveBitmap(String name,Bitmap bitmap){
if (!isSdcard()) {
return;
}
//获取图片的完整存储路径,以图片的网址为图片名存储
String fileName=getFile()+"/"+name;
//创建字符数组输出流来将图片写到sd卡里
ByteArrayOutputStream bos=new ByteArrayOutputStream();
//图片压缩,并且将文件转换成流,在写到指定的文件中去
bitmap.compress(CompressFormat.PNG, 100, bos);
File file=new File(fileName);
try {
FileOutputStream out=new FileOutputStream(file);
out.write(bos.toByteArray());
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//读取图片的方法
public Bitmap getBitmap(String name){
Bitmap bitmap=null;
if (!isSdcard()) {
return bitmap;
}
//获取图片的存储路径
String path=getFile()+"/"+name;
bitmap=BitmapFactory.decodeFile(path);
return bitmap;
}

}

图片三级缓存类

Loader.class

package cn.bgs.imagethreelevelload.loader;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.MalformedURLException;

import java.net.URL;

import java.net.URLConnection;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Set;

import java.util.concurrent.Executor;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import android.annotation.SuppressLint;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.support.v4.util.LruCache;

import android.widget.ImageView;

import cn.bgs.imagethreelevelload.utils.FileUtils;

/**

 * 图片三级缓存的类

 * */

@SuppressLint("NewApi")

public class Loader {
private FileUtils fileutils;
private Context context;
//声明一个可以开启线程的最大数量
private final static int MAX_POOLS=5;
//声明一个线程池
private ExecutorService thread_pool;
//创建一个存储图片控件的set集合
private Set<ImageView> imgs=new HashSet<ImageView>();
//规定每个线程的最大内存
private int MAX_size=(int) (Runtime.getRuntime().maxMemory())/1024/5;
//LruCache 类似于强引用内存,一旦超出最大值会自动将前面的扔出缓存,便于垃圾回收机制回收
//LruCache 存储方式和map类似,使用K V 存值,便于图片查找
private LruCache<String, Bitmap> lru=new LruCache<String, Bitmap>(MAX_size){
@Override
protected int sizeOf(String key, Bitmap value) {
// TODO Auto-generated method stub
return value.getByteCount()/1024;
}
};
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
if (msg.what==1) {
Bitmap bitmap=(Bitmap) msg.obj;
String imgname=msg.getData().getString("imgname");
Iterator<ImageView> it = imgs.iterator();
while(it.hasNex
baca
t()){
ImageView imageView = it.next();
String tag = (String) imageView.getTag();
if (tag.equals(imgname)) {
imageView.setImageBitmap(bitmap);
return;
}
}
}
}
};
public void load(String urlpath,ImageView img,Context context){
if (urlpath==null) {
return;
}
if (img==null) {
return;
}
this.context=context;
Bitmap bitmap;
//将网址过滤成图片的名字
String imgname=urlpath.replace("/","").replace(".", "").replace("_", "").replace(":","");
//图片控件保存到tag中
//为了避免图片错位,将图片对应的名字存储到相应的控件中,以便以后进行比较
img.setTag(imgname);
//将img添加到set集合中
imgs.add(img);
//从lru中获取图片
bitmap =lru.get(imgname);
if (bitmap!=null) {
img.setImageBitmap(bitmap);
return;
}
//如果lru中没有则从sd卡中获取
if (fileutils==null) {
fileutils=new FileUtils(context);
bitmap=fileutils.getBitmap(imgname);
if (bitmap!=null) {
img.setImageBitmap(bitmap);
lru.put(imgname, bitmap);
return;
}
}
//如果前面两个都没有则从网络上下载
if (thread_pool==null) {
thread_pool=Executors.newFixedThreadPool(MAX_POOLS);
}
thread_pool.execute(new ImageThread(urlpath));
}
private class ImageThread implements Runnable{
private String urlpath;
public ImageThread(String urlpath){
this.urlpath=urlpath;
}
@Override
public void run() {
try {
URL url=new URL(urlpath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(60*1000);
connection.setReadTimeout(60*1000);
connection.setDoInput(true);
connection.setRequestMethod("POST");
InputStream is = connection.getInputStream();
Bitmap bitmap=BitmapFactory.decodeStream(is);
String imgname=urlpath.replace("/","").replace(".", "").replace("_", "").replace(":","");
//将下载下来的图片再次加载到lru和sd卡中
if (bitmap!=null) {
fileutils.saveBitmap(imgname, bitmap);
lru.put(imgname, bitmap);
Message msg=handler.obtainMessage();
msg.what=1;
msg.obj=bitmap;
Bundle bundle=new Bundle();
bundle.putString("imgname", imgname);
msg.setData(bundle);
handler.sendMessage(msg);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

}

}

XML

activity_main.XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity" 

    android:orientation="vertical">

    
<Button 
android:id="@+id/mBtn"
   
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:text="点击下载"
   />
<ImageView 
   android:id="@+id/mImg"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   />

</LinearLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图片 缓存 imageview