Android 图片缓存处理

来源:互联网 发布:搜狐网络大厦饭卡 编辑:程序博客网 时间:2024/05/22 03:43

主要从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;// 在这定义一个bitmappublic Bitmap mybitmap;private Handler handler = new Handler() {@Overridepublic 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地址@Overrideprotected 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() {@Overridepublic 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> {@Overrideprotected void onPreExecute() { super.onPreExecute();pro.show();}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);pro.setProgress(values[0]);}@Overrideprotected 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);}@Overrideprotected 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 ;//imageViewprivate 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;}@Overrideprotected void onPreExecute() { // 执行前时super.onPreExecute();pro.show();}@Overrideprotected void onProgressUpdate(Integer... values) {// 更新进度条的super.onProgressUpdate(values);pro.setProgress(values[0]);}@Overrideprotected 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);}@Overrideprotected 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();      }  }  

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


0 0
原创粉丝点击