下面是编程之家 jb51.cc 通过网络收集整理的代码片段。
编程之家小编现在分享给大家,也给大家做个参考。
import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.concurrent.RejectedExecutionException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpGet; import xiaogang.enif.utils.HttpManager; import xiaogang.enif.utils.IOUtils; import xiaogang.enif.utils.LogUtils; import xiaogang.enif.utils.LruCache; import android.app.ActivityManager; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.os.AsyncTask; import android.text.TextUtils; import android.util.AttributeSet; import android.widget.ImageView; public class CacheView extends ImageView { private static final int DEFAULT_RES_ID = 0; private int mDefaultImage = DEFAULT_RES_ID; private static LruCache<String,Bitmap> mLruCache; private static HashMap<Integer,SoftReference<Bitmap>> mResImage; private Context mContext; private LogUtils mLog = LogUtils.getLog(CacheView.class); public CacheView(Context context,AttributeSet attrs,int defStyle) { super(context,attrs,defStyle); init(context); } public CacheView(Context context,AttributeSet attrs) { super(context,attrs); init(context); } public CacheView(Context context) { super(context); init(context); } private void init(Context context) { mContext = context; if (mLruCache == null) { final int cacheSize = getCacheSize(context); mLruCache = new LruCache<String,Bitmap>(cacheSize) { @Override protected int sizeOf(String key,Bitmap bitmap) { // The cache size will be measured in bytes rather than // number of items. return bitmap.getRowBytes() * bitmap.getHeight(); } @Override protected void entryRemoved(boolean evicted,String key,Bitmap oldValue,Bitmap newValue) { if (evicted && oldValue != null && !oldValue.isRecycled()) { oldValue.recycle(); oldValue = null; } } }; } if (mResImage == null) { mResImage = new HashMap<Integer,SoftReference<Bitmap>>(); } } @Override protected void onDraw(Canvas canvas) { BitmapDrawable drawable = (BitmapDrawable)getDrawable(); if (drawable == null) { setDefaultImage(); } else { if (drawable.getBitmap() == null || drawable.getBitmap().isRecycled()) { setDefaultImage(); } } try { super.onDraw(canvas); } catch(RuntimeException ex) { } } public void setImageUrl(String url,int resId) { setTag(url); Bitmap bitmap = getBitmapFromCache(url); if (bitmap == null || bitmap.isRecycled()) { mDefaultImage = resId; setDefaultImage(); try { new DownloadTask().execute(url); } catch (RejectedExecutionException e) { // do nothing,just keep not crash } } else { setImageBitmap(bitmap); } } private void setDefaultImage() { if (mDefaultImage != DEFAULT_RES_ID) { setImageBitmap(getDefaultBitmap(mContext)); } } private Bitmap getDefaultBitmap(Context context) { SoftReference<Bitmap> loading = mResImage.get(mDefaultImage); if (loading == null || loading.get() == null || loading.get().isRecycled()) { loading = new SoftReference<Bitmap>(BitmapFactory.decodeResource( context.getResources(),mDefaultImage)); mResImage.put(mDefaultImage,loading); } return loading.get(); } private class DownloadTask extends AsyncTask<String,Void,Bitmap> { private String mParams; @Override public Bitmap doInBackground(String... params) { mParams = params[0]; final Bitmap bm = download(mParams); addBitmapToCache(mParams,bm); return bm; } @Override public void onPostExecute(Bitmap bitmap) { String tag = (String)getTag(); if (!TextUtils.isEmpty(tag) && tag.equals(mParams)) { if (bitmap != null) { setImageBitmap(bitmap); } } } }; /* * An InputStream that skips the exact number of bytes provided,unless it * reaches EOF. */ static class FlushedInputStream extends FilterInputStream { public FlushedInputStream(InputStream inputStream) { super(inputStream); } @Override public long skip(long n) throws IOException { long totalBytesSkipped = 0L; while (totalBytesSkipped < n) { long bytesSkipped = in.skip(n - totalBytesSkipped); if (bytesSkipped == 0L) { int b = read(); if (b < 0) { break; // we reached EOF } else { bytesSkipped = 1; // we read one byte } } totalBytesSkipped += bytesSkipped; } return totalBytesSkipped; } } private Bitmap download(String url) { InputStream in = null; HttpEntity entity = null; Bitmap bmp = null; try { final HttpGet get = new HttpGet(url); final HttpResponse response = HttpManager.execute(mContext,get); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { entity = response.getEntity(); in = entity.getContent(); try { bmp = getDecodeBitmap(in,url); } catch (OutOfMemoryError err) { Runtime.getRuntime().gc(); bmp = getDecodeBitmap(in,url); } } else { get.abort(); return bmp; } addBitmapToCache(url,bmp); } catch (IOException e) { return bmp; } finally { IOUtils.closeStream(in); } return bmp; } private final Bitmap getDecodeBitmap(InputStream in,String url) { Options options = new Options(); options.inPurgeable = true; options.inInputShareable = true; return BitmapFactory.decodeStream(new FlushedInputStream(in),null,options); } private final void addBitmapToCache(String url,Bitmap bitmap) { if (bitmap != null) { mLruCache.put(url,bitmap); Runtime.getRuntime().gc(); } } private final Bitmap getBitmapFromCache(String url) { return mLruCache.get(url); } private int getCacheSize(Context context) { // According to the phone memory,set a proper cache size for LRU cache // dynamically. final ActivityManager am = (ActivityManager)context .getSystemService(Context.ACTIVITY_SERVICE); final int memClass = am.getMemoryClass(); int cacheSize; if (memClass <= 24) { cacheSize = (memClass << 20) / 24; } else if (memClass <= 36) { cacheSize = (memClass << 20) / 18; } else if (memClass <= 48) { cacheSize = (memClass << 20) / 12; } else { cacheSize = (memClass << 20) >> 3; } mLog.debug("cacheSize == "+cacheSize); System.out.println("cacheSize == "+cacheSize); return cacheSize; } public static void recycle() { if (mLruCache != null && !mLruCache.isEmpty()) { mLruCache.evictAll(); mLruCache = null; } if (mResImage != null) { for (SoftReference<Bitmap> reference : mResImage.values()) { Bitmap bitmap = reference.get(); if (bitmap != null && !bitmap.isRecycled()) { bitmap.recycle(); bitmap = null; } } mResImage = null; } } } 说明: 1)entryRemoved 在做Bitmap recyle 的时候的三个条件缺一不可 2)onDraw 里面判断图片是否被回收,如果回收 需要设置默认的图片 3)add bitmap 到cache 的时候 Runtime.getRuntime().gc 的调用
以上是编程之家(jb51.cc)为你收集整理的全部代码内容,希望文章能够帮你解决所遇到的程序开发问题。
如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。