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;}}
两个类分别如下:
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
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android图片缓存处理
- Android 图片缓存处理
- android 新闻图片加载,缓存处理
- 基于Android的图片缓存处理
- android 图片处理(压缩与缓存)
- 图片处理 缓存
- 图片处理,三级缓存
- 三级缓存处理图片
- Android中的图片处理(包括缓存、大小、优化等)
- Android 加载大量图片的三级缓存处理
- 每天一个linux命令(50):crontab命令
- 战鹰兮箜箜
- JAVA面向对象思想
- 天地又何如
- Sonatype Nexus 搭建Maven 私服
- Android 图片缓存处理
- unity优化的一些建议(代码+文字)
- JavaScript判断一个对象是否为空,未定义
- PHP面向对象(OOP)编程完全教程:4.如何抽象出一个类?
- 怎么跳出MySQL的10个大坑
- HDU 5162 简单排序
- 未来四年的计划目标
- iOS学习之WebView的使用--实现打开网页
- 第二十六次codeforces竞技结束 #286 Div 2