欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Android处理网络和图片的工具类,,1:网络的底层环境 采用

来源: javaer 分享于  点击 2441 次 点评:253

Android处理网络和图片的工具类,,1:网络的底层环境 采用


1:网络的底层环境 采用apache 的httpClient 链接池框架

2:图片缓存采用基于LRU 的算法

3:网络接口采用监听者模式

4 包含图片的OOM 处理(及时回收处理技术的应用)

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 &amp;&amp; oldValue != null &amp;&amp; !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) &amp;&amp; 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 &amp;&amp; !mLruCache.isEmpty()) {            mLruCache.evictAll();            mLruCache = null;        }        if (mResImage != null) {            for (SoftReference<Bitmap> reference : mResImage.values()) {                Bitmap bitmap = reference.get();                if (bitmap != null &amp;&amp; !bitmap.isRecycled()) {                    bitmap.recycle();                    bitmap = null;                }            }            mResImage = null;        }    }}说明:1)entryRemoved 在做Bitmap recyle 的时候的三个条件缺一不可2)onDraw 里面判断图片是否被回收,如果回收  需要设置默认的图片3)add bitmap 到cache 的时候 Runtime.getRuntime().gc 的调用
相关栏目:

用户点评