Android 图片缓存处理

主要从http://blog.csdn.net/a79412906/article/details/10180583   COPY过来的

首先是主acitivity的代码:

package com.baoxiu123.imageCache;
public class MainActivity extends ActionBarActivity {
	private ImageMemoryCache memoryCache;
	private ImageFileCache fileCache;
	// 在这定义一个bitmap
	public Bitmap mybitmap;

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (msg.what == CHANG_UI) {
				// pro.setVisibility(View.GONE);
				pro.dismiss();
				Bitmap bitmap = (Bitmap) msg.obj;
				im.setImageBitmap(bitmap);

			} else if (msg.what == WAIT_UI) {
				Toast.makeText(getApplicationContext(), "OK!正在为您执行您想要的操作!", 1)
						.show();			
			} 
		}
	};
	ProgressDialog pro = null;  //图片从网上下载的进度条
	public ImageView im = null; 
	protected String DATA = null; //图片url地址

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_main);
		// 用来缓存的两个对象生成
		memoryCache = new ImageMemoryCache(this);
		fileCache = new ImageFileCache();

		im = (ImageView) findViewById(R.id.imageView1);
		pro = new ProgressDialog(this);
		pro.setTitle("提示");
		pro.setMessage("正在打开中,请稍等!");
		pro.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //进度条样式
		mybutton = (Button) findViewById(R.id.button1);
		mybutton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
                                  init();
                               getBitmap(DATA);
			}
		});
	}

	public void getBitmap(String url) {
		// 从内存缓存中获取图片
		
		Bitmap result = memoryCache.getBitmapFromCache(url);
		if (result == null) {
			// 文件缓存中获取
			result = fileCache.getImage(url);
			if (result == null) {
				// 从网络获取
				new MyTask().execute(DATA);
				result = mybitmap;
				if (result != null) {
					fileCache.saveBitmap(result, url);
					memoryCache.addBitmapToCache(url, result);
				}
			} else {
				// 添加到内存缓存
				memoryCache.addBitmapToCache(url, result);
			}
		}
		im.setImageBitmap(result);
	}

	public final void inis() {
			DATA = "http://www.jotop.com/uploadfile/2014/0514/20140514111707500.png";
	}

	public class MyTask extends AsyncTask<String, Integer, Bitmap> {
		@Override
		protected void onPreExecute() { 
			super.onPreExecute();
			pro.show();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			pro.setProgress(values[0]);
		}

		@Override
		protected void onPostExecute(Bitmap result) {
			super.onPostExecute(result);
			pro.dismiss();//执行完了 ,就让进度条消失
			mybitmap = result;
			if (result != null) {//如果从网上获取到了图片,就把它给缓存起来
				fileCache.saveBitmap(result, DATA);
				memoryCache.addBitmapToCache(DATA, result);
			}
			im.setImageBitmap(result);
		}

		@Override
		protected Bitmap doInBackground(String... arg0) {
			Bitmap bitmap = null;
			try {
				HttpClient httpclient = new DefaultHttpClient();
				HttpGet httpget = new HttpGet(arg0[0]);
				HttpResponse httpresponse = httpclient.execute(httpget);
				ByteArrayOutputStream outputstream = new ByteArrayOutputStream();
				InputStream inputstream = null;
				if (httpresponse.getStatusLine().getStatusCode() == 200) {
					inputstream = httpresponse.getEntity().getContent();
					long file_length = httpresponse.getEntity()
							.getContentLength();
					int len = 0;
					byte[] data = new byte[1024];
					int total_lenth = 0;
					while ((len = inputstream.read(data)) != -1) {
						total_lenth += len;
						int value = (int) ((total_lenth / (float) file_length) * 100);
						publishProgress(value);
						outputstream.write(data, 0, len);
					}
					byte[] result = outputstream.toByteArray();
					bitmap = BitmapFactory.decodeByteArray(result, 0,
							result.length);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return bitmap;
		}
	}

}

最终经过优化,将图片下载做成一个专门的类,感觉好一点,代码如下:

package com.baoxiu123.second.imageUtils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;

public class ImageDownLoad extends AsyncTask<String, Integer, Bitmap> {
	private String urlStr = "" ;//下载地址
	private ProgressDialog pro;//进度条
	private ImageView im ;//imageView
	private ImageMemoryCache memoryCache; //内存缓冲
	private ImageFileCache fileCache;//文件缓冲
	private Bitmap mybitmap;
	


	public ImageDownLoad(String urlStr, ProgressDialog pro,
			ImageView im, ImageMemoryCache memoryCache, ImageFileCache fileCache) {
		super();
		this.urlStr = urlStr;
		this.pro = pro;
		this.im = im;
		this.memoryCache = memoryCache;
		this.fileCache = fileCache;
	}

	@Override
	protected void onPreExecute() { // 执行前时
		super.onPreExecute();
		pro.show();
	}

	@Override
	protected void onProgressUpdate(Integer... values) {// 更新进度条的
		super.onProgressUpdate(values);
		pro.setProgress(values[0]);
	}

	@Override
	protected void onPostExecute(Bitmap result) {// 执行完毕时
		super.onPostExecute(result);
		pro.dismiss();

		mybitmap = result;
		if (result != null) {
			Log.i("MSG", "result != null");
			fileCache.saveBitmap(result, urlStr);
			Log.i("MSG", "fileCache.saveBitmap(result, url)");
			memoryCache.addBitmapToCache(urlStr, result);
		}
		im.setImageBitmap(result);
	}

	@Override
	protected Bitmap doInBackground(String... arg0) {
		Bitmap bitmap = null;
		try {
			HttpClient httpclient = new DefaultHttpClient();
			HttpGet httpget = new HttpGet(arg0[0]);
			HttpResponse httpresponse = httpclient.execute(httpget);
			ByteArrayOutputStream outputstream = new ByteArrayOutputStream();
			InputStream inputstream = null;
			if (httpresponse.getStatusLine().getStatusCode() == 200) {
				inputstream = httpresponse.getEntity().getContent();
				long file_length = httpresponse.getEntity()
						.getContentLength();
				int len = 0;
				byte[] data = new byte[1024];
				int total_lenth = 0;
				while ((len = inputstream.read(data)) != -1) {
					total_lenth += len;
					int value = (int) ((total_lenth / (float) file_length) * 100);
					publishProgress(value);
					outputstream.write(data, 0, len);
				}
				byte[] result = outputstream.toByteArray();
				bitmap = BitmapFactory.decodeByteArray(result, 0,
						result.length);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bitmap;
	}
}






后面两个就是直接从http://blog.csdn.net/a79412906/article/details/10180583这个博客里复制过来的了,至于内部细节,我现在还不怎么清楚,反正经我测试后,有用,达到了我想要的效果

两个类分别如下:

package com.baoxiu123.second.imageUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Comparator;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;

public class ImageFileCache {  
    private static final String CACHDIR = "ImgCach";  
    private static final String WHOLESALE_CONV = ".cach";  
                                                              
    private static final int MB = 1024*1024;  
    private static final int CACHE_SIZE = 10;  
    private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;  
                                                                  
    public ImageFileCache() {  
        //清理文件缓存  
        removeCache(getDirectory());  
    }  
                                                                  
    /** 从缓存中获取图片 **/  
    public Bitmap getImage(final String url) {      
        final String path = getDirectory() + "/" + convertUrlToFileName(url);  
        File file = new File(path);  
        if (file.exists()) {  
            Bitmap bmp = BitmapFactory.decodeFile(path);  
            if (bmp == null) {  
                file.delete();  
            } else {  
                updateFileTime(path);  
                return bmp;  
            }  
        }  
        return null;  
    }  
                                                                  
    /** 将图片存入文件缓存 **/  
    public void saveBitmap(Bitmap bm, String url) {  
        if (bm == null) {  
            return;  
        }  
        //判断sdcard上的空间  
        if (FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {  
            //SD空间不足  
            return;  
        }  
        String filename = convertUrlToFileName(url);  
        String dir = getDirectory();  
        File dirFile = new File(dir);  
        if (!dirFile.exists())  
            dirFile.mkdirs();  
        File file = new File(dir +"/" + filename);  
        Log.i("XXXX", dir +"/" + filename);
        try {  
            file.createNewFile();  
            OutputStream outStream = new FileOutputStream(file);  
            bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);  
            outStream.flush();  
            outStream.close(); 
            
            Log.i("MSG", "image fulled");
        } catch (FileNotFoundException e) {  
            Log.w("ImageFileCache", "FileNotFoundException");  
        } catch (IOException e) {  
            Log.w("ImageFileCache", "IOException");  
        }  
    }   
                                                                  
    /** 
     * 计算存储目录下的文件大小, 
     * 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定 
     * 那么删除40%最近没有被使用的文件 
     */  
    private boolean removeCache(String dirPath) {  
        File dir = new File(dirPath);  
        File[] files = dir.listFiles();  
        if (files == null) {  
            return true;  
        }  
        if (!android.os.Environment.getExternalStorageState().equals(  
                android.os.Environment.MEDIA_MOUNTED)) {  
            return false;  
        }  
                                                              
        int dirSize = 0;  
        for (int i = 0; i < files.length; i++) {  
            if (files[i].getName().contains(WHOLESALE_CONV)) {  
                dirSize += files[i].length();  
            }  
        }  
                                                              
        if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {  
            int removeFactor = (int) ((0.4 * files.length) + 1);  
            Arrays.sort(files, new FileLastModifSort());  
            for (int i = 0; i < removeFactor; i++) {  
                if (files[i].getName().contains(WHOLESALE_CONV)) {  
                    files[i].delete();  
                }  
            }  
        }  
                                                              
        if (freeSpaceOnSd() <= CACHE_SIZE) {  
            return false;  
        }  
                                                                      
        return true;  
    }  
                                                                  
    /** 修改文件的最后修改时间 **/  
    public void updateFileTime(String path) {  
        File file = new File(path);  
        long newModifiedTime = System.currentTimeMillis();  
        file.setLastModified(newModifiedTime);  
    }  
                                                                  
    /** 计算sdcard上的剩余空间 **/  
    private int freeSpaceOnSd() {  
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());  
        double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;  
        return (int) sdFreeMB;  
    }   
                                                                  
    /** 将url转成文件名 **/  
    private String convertUrlToFileName(String url) {  
        String[] strs = url.split("/");  
        return strs[strs.length - 1] + WHOLESALE_CONV;  
    }  
                                                                  
    /** 获得缓存目录 **/  
    private String getDirectory() {  
        String dir = getSDPath() + "/" + CACHDIR;  
        return dir;  
    }  
                                                                  
    /** 取SD卡路径 **/  
    private String getSDPath() {  
        File sdDir = null;  
        boolean sdCardExist = Environment.getExternalStorageState().equals(  
                android.os.Environment.MEDIA_MOUNTED);  //判断sd卡是否存在  
        if (sdCardExist) {  
            sdDir = Environment.getExternalStorageDirectory();  //获取根目录  
        }  
        if (sdDir != null) {  
            return sdDir.toString();  
        } else {  
            return "";  
        }  
    }   
                                                              
    /** 
     * 根据文件的最后修改时间进行排序 
     */  
    private class FileLastModifSort implements Comparator<File> {  
        public int compare(File arg0, File arg1) {  
            if (arg0.lastModified() > arg1.lastModified()) {  
                return 1;  
            } else if (arg0.lastModified() == arg1.lastModified()) {  
                return 0;  
            } else {  
                return -1;  
            }  
        }  
    }  
                                                              
}  

another:

package com.baoxiu123.second.imageUtils;

import java.lang.ref.SoftReference;
import java.util.LinkedHashMap;
import java.util.Map.Entry;

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;

public class ImageMemoryCache {  
    /** 
     * 从内存读取数据速度是最快的,为了更大限度使用内存,这里使用了两层缓存。 
     * 硬引用缓存不会轻易被回收,用来保存常用数据,不常用的转入软引用缓存。 
     */  
    private static final int SOFT_CACHE_SIZE = 15;  //软引用缓存容量  
    private static LruCache<String, Bitmap> mLruCache;  //硬引用缓存  
    private static LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache;  //软引用缓存  
                                                                                            
    public ImageMemoryCache(Context context) {  
        int memClass = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();  
        int cacheSize = 1024 * 1024 * memClass / 4;  //硬引用缓存容量,为系统可用内存的1/4  
        mLruCache = new LruCache<String, Bitmap>(cacheSize) {  
            @Override  
            protected int sizeOf(String key, Bitmap value) {  
                if (value != null)  
                    return value.getRowBytes() * value.getHeight();  
                else  
                    return 0;  
            }  
                                                                                            
            @Override  
            protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {  
                if (oldValue != null)  
                    // 硬引用缓存容量满的时候,会根据LRU算法把最近没有被使用的图片转入此软引用缓存  
                    mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));  
            }  
        };  
        mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>(SOFT_CACHE_SIZE, 0.75f, true) {  
            private static final long serialVersionUID = 6040103833179403725L;  
            @Override  
            protected boolean removeEldestEntry(Entry<String, SoftReference<Bitmap>> eldest) {  
                if (size() > SOFT_CACHE_SIZE){      
                    return true;    
                }    
                return false;   
            }  
        };  
    }  
                                                                                    
    /** 
     * 从缓存中获取图片 
     */  
    public Bitmap getBitmapFromCache(String url) {  
        Bitmap bitmap;  
        //先从硬引用缓存中获取  
        synchronized (mLruCache) {  
            bitmap = mLruCache.get(url);  
            if (bitmap != null) {  
                //如果找到的话,把元素移到LinkedHashMap的最前面,从而保证在LRU算法中是最后被删除  
                mLruCache.remove(url);  
                mLruCache.put(url, bitmap);  
                return bitmap;  
            }  
        }  
        //如果硬引用缓存中找不到,到软引用缓存中找  
        synchronized (mSoftCache) {   
            SoftReference<Bitmap> bitmapReference = mSoftCache.get(url);  
            if (bitmapReference != null) {  
                bitmap = bitmapReference.get();  
                if (bitmap != null) {  
                    //将图片移回硬缓存  
                    mLruCache.put(url, bitmap);  
                    mSoftCache.remove(url);  
                    return bitmap;  
                } else {  
                    mSoftCache.remove(url);  
                }  
            }  
        }  
        return null;  
    }   
                                                                                    
    /** 
     * 添加图片到缓存  
     */  
    public void addBitmapToCache(String url, Bitmap bitmap) {  
        if (bitmap != null) {  
            synchronized (mLruCache) {  
                mLruCache.put(url, bitmap);  
            }  
        }  
    }  
                                                                                    
    public void clearCache() {  
        mSoftCache.clear();  
    }  
}  

更多解释,到该原处去看: 点击打开原处链接


你可能感兴趣的:(Android 图片缓存处理)