图片的三级缓存原理代码

来源:互联网 发布:laravel 阿里云邮箱 编辑:程序博客网 时间:2024/05/07 04:22

图片的三级缓存思路在前面的博客已经转载了,现在写出三级缓存的原理代码

需要写两个类,一个是图片的三级缓存类,还有一个是文件操作工具类:存储和读取图片

文件操作工具类:  存储和读取图片

public class FileUtils {private Context ctx;public FileUtils(Context ctx){this.ctx=ctx;}
判断SD卡是否存在的方法--->存在返回true  不存在返回false

Environment.getExternalStorageState():获取sd卡的状态  Environment.MEDIA_MOUNTED:当前SD存在

private boolean ISSDcard(){if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {return true;}return false;}
获取文件目录的方法    /mnt/sdcard/android/data/catch/name;
private String getFile(){String str = null;str=ctx.getExternalCacheDir().getAbsolutePath();return str;}
存储图片的方法

public void saveBitmap(String name,Bitmap bitmap){//判断sdk是否存在,不存在直接return;if (!ISSDcard()) {return;}//获取图片完整存储路径:以图片网址为图片名称存储   /mnt/sdcard/android/data/catch/nameString filename = getFile()+"/"+name;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 (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}

读取图片的方法 

public Bitmap readBitmap(String name){Bitmap bitmap=null;if(!ISSDcard())return bitmap;//获取图片存储的完整路径String filename=getFile()+"/"+name;bitmap=BitmapFactory.decodeFile(filename);return bitmap;}}

图片的三级缓存类

@SuppressLint("NewApi")public class Loader {private FileUtils fileutils;//工具类private Context ctx;private final static int MAX_POOLS=5;//声明一个最大地开启线程数private ExecutorService thread_pool;//声明一个线程池private Set<ImageView> imgs=new HashSet<ImageView>();//创建一个存储图片控件的set集合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){@Overrideprotected int sizeOf(String key, Bitmap value) {// TODO Auto-generated method stubreturn value.getByteCount()/1024;}};
private Handler mHandler=new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);if(msg.what==200){Bitmap bitmap=(Bitmap) msg.obj;String name=msg.getData().getString("imgname");//遍历set集合,进行对比Iterator<ImageView> it = imgs.iterator();while(it.hasNext()){ImageView img = it.next();String tag=(String) img.getTag();//将子线程出来的图片名称和控件保存的相对应的图片名称进行比较,如果相同就设置if(tag.equals(name)){img.setImageBitmap(bitmap);return;}}}}};
public void Load(String name,ImageView img,Context ctx){//为空直接跳出if(name==null)return;if(img==null)return;this.ctx=ctx;Bitmap bitmap;//name 进行过滤String name1=name.replace("/", "").replace(".", "").replace(":", "").replace("_", "");//img.添加tagimg.setTag(name1);//为避免出现图片错位,将图片名存储在其想对应的控件中,方便以后进行对比设置//将img添加到set集合imgs.add(img);//从lru中查找图片bitmap=lru.get(name1);//K V-->从Lru中获取图片if(bitmap!=null){img.setImageBitmap(bitmap);return;}//从本地sd中获取图片if(fileutils==null){fileutils=new FileUtils(ctx);bitmap=fileutils.readBitmap(name1);if(bitmap!=null){img.setImageBitmap(bitmap);//将图片添加到Lru中lru.put(name1, bitmap);return;}}//从网络下载if(thread_pool==null){thread_pool=Executors.newFixedThreadPool(MAX_POOLS);}//准备网络加载图片thread_pool.execute(new ImgThread(name));}
图片异步加载内部类
private class ImgThread implements Runnable{private String name;public ImgThread(String name){this.name=name;}@Overridepublic void run() {//开始网络下载try {URL url=new URL(name);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(30*1000);conn.setReadTimeout(30*1000);conn.setDoInput(true);conn.setRequestMethod("GET");Bitmap bitmap=BitmapFactory.decodeStream(conn.getInputStream());String name1=name.replace("/", "").replace(".", "").replace(":", "").replace("_", "");//将下载下来的图片再次添加到SD卡和lru中if(bitmap!=null){fileutils.saveBitmap(name1, bitmap);lru.put(name1, bitmap);Message msg=hand.obtainMessage();msg.what=200;msg.obj=bitmap;Bundle data=new Bundle();data.putString("imgname", name1);msg.setData(data);mHandler.sendMessage(msg);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

MainActivity中这样写:

public class MainActivity extends Activity implements OnClickListener {    private Button bt;private ImageView iv;private Loader loader;private String name="http://p3.so.qhimg.com/bdr/326__/t01488cea27c27cf588.jpg";@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        loader=new Loader();}private void initView() {// TODO Auto-generated method stubbt = (Button) findViewById(R.id.bt);              iv = (ImageView) findViewById(R.id.iv);        bt.setOnClickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubloader.Load(name, iv, this);}}

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"    android:orientation="vertical"    tools:context=".MainActivity" >    <Button        android:id="@+id/bt"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="点击加载" />    <ImageView        android:id="@+id/iv"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>

最后一定不要忘了在清单文件中注册

0 0
原创粉丝点击