Android LruCache图片缓存使用(二)

来源:互联网 发布:mac 安装mysql详解 编辑:程序博客网 时间:2024/05/16 17:03

从上一篇文章LruCache的源码简介中,我想我们可以知道LruCache的基本实现原理了!如果没有了解的可以先看看LruCache的基本介绍。

那在实际开发中我们如何使用LruCache呢?

首先,我们要覆写sizeof这个方法。如下:

int maxCache = (int) (Runtime.getRuntime().maxMemory() / 1024);//得到应用的最大可用内存        int cacheSize = maxCache / 8; //一般情况下最多为可用内存的1/8        mLruCache = new LruCache<String,Bitmap>(cacheSize){            @Override            protected int sizeOf(String key, Bitmap value) {                if(value != null)                    return value.getByteCount() / 1024;                return 0;            }        };

然后,检查LruCache的缓存中是否有对应的key值,如果有就返回对应的Bitmap,如果没有则开异步线程去下载图片后再存入LruCache。其中核心代码如下:

    /**     * 通过key值从LruCache中获取缓存对象     *      * @param key     * @return 如果LruCache存在该key则返回缓存的bitmap,否则返回null     */    private Bitmap getBitmapFromCache(String key){        return mLruCache.get(key);    }    /**     * 通过key将Bitmap缓存到LruCache中     *      * @param key     * @param bitmap     */    private void putBitmapToCache(String key, Bitmap bitmap){        if(getBitmapFromCache(key) == null && bitmap != null)            mLruCache.put(key, bitmap);    }

下面我们直接来看一个简单的demo

MainActivity:

package com.richardli.lrucachedemo_1;import android.app.Activity;import android.os.Bundle;import android.widget.GridView;public class MainActivity extends Activity {    private GridView mGridView;    private LruCacheImgAdapter mAdapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init(){        mGridView = (GridView) findViewById(R.id.imgsGridView);        mAdapter = new LruCacheImgAdapter(this, imageThumbUrls ,mGridView);        mGridView.setAdapter(mAdapter);    }    @Override    protected void onDestroy() {        super.onDestroy();        mAdapter.cancelAllDowanTask();        mAdapter.clearAllCache();        mAdapter = null;        System.gc();    }    /**     * 图片资源从郭神博客中抠出来的,呵呵...     */    public final static String[] imageThumbUrls = new String[] {          "http://img.my.csdn.net/uploads/201407/26/1406383299_1976.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383291_6518.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383291_8239.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383290_9329.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383290_1042.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383275_3977.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383265_8550.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383264_3954.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383264_4787.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383264_8243.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383248_3693.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383243_5120.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383242_3127.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383242_9576.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383242_1721.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383219_5806.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383214_7794.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383213_4418.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383213_3557.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383210_8779.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383172_4577.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383166_3407.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383166_2224.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383166_7301.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383165_7197.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383150_8410.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383131_3736.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383130_5094.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383130_7393.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383129_8813.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383100_3554.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383093_7894.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383092_2432.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383092_3071.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383091_3119.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383059_6589.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383059_8814.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383059_2237.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383058_4330.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406383038_3602.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382942_3079.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382942_8125.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382942_4881.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382941_4559.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382941_3845.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382924_8955.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382923_2141.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382923_8437.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382922_6166.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382922_4843.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382905_5804.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382904_3362.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382904_2312.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382904_4960.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382900_2418.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382881_4490.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382881_5935.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382880_3865.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382880_4662.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382879_2553.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382862_5375.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382862_1748.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382861_7618.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382861_8606.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382861_8949.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382841_9821.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382840_6603.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382840_2405.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382840_6354.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382839_5779.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382810_7578.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382810_2436.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382809_3883.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382809_6269.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382808_4179.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382790_8326.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382789_7174.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382789_5170.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382789_4118.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382788_9532.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382767_3184.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382767_4772.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382766_4924.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382766_5762.jpg",          "http://img.my.csdn.net/uploads/201407/26/1406382765_7341.jpg"      };  }

LruCacheImgAdapter适配器:

package com.richardli.lrucachedemo_1;import java.io.IOException;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.ArrayList;import java.util.List;import javax.net.ssl.HttpsURLConnection;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.support.v4.util.LruCache;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.ImageView;public class LruCacheImgAdapter extends BaseAdapter implements OnScrollListener{    private Context mContext;    private LayoutInflater mInflater;    private String[] mImgsList;    private GridView mGridView;    private LruCache<String, Bitmap> mLruCache;//所有图片缓存    private List<DownloadAsyncTask> mDownloadTastAllList; //所有异步下载集合    private int mFirstVisibleItem;//当前可见列表的第一项    private int mVisibleItemCount;//当前可见表项个数    private boolean isFirstCome = true;// 是否是第一次进入加载    public LruCacheImgAdapter(Context ctx , String[] imgs , GridView mGridView){        this.mContext = ctx;        this.mImgsList = imgs;        this.mGridView = mGridView;        this.mGridView.setOnScrollListener(this);        mInflater = LayoutInflater.from(mContext);        mDownloadTastAllList = new ArrayList<LruCacheImgAdapter.DownloadAsyncTask>();        initLruCache();    }    private void initLruCache(){        int maxCache = (int) (Runtime.getRuntime().maxMemory() / 1024);//得到应用的最大可用内存        int cacheSize = maxCache / 8; //一般情况下最多为可用内存的1/8        mLruCache = new LruCache<String,Bitmap>(cacheSize){            @Override            protected int sizeOf(String key, Bitmap value) {                if(value != null)                    return value.getByteCount() / 1024;                return 0;            }        };    }    @Override    public int getCount() {        return mImgsList.length;    }    @Override    public Object getItem(int position) {        return mImgsList[position];    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder mViewHolder = null;        if(convertView == null){            convertView = mInflater.inflate(R.layout.img_grid_item_layout, parent , false);            mViewHolder = new ViewHolder();            mViewHolder.mImagsView = (ImageView) convertView.findViewById(R.id.img_show_iv);            convertView.setTag(mViewHolder);        }else{            mViewHolder = (ViewHolder) convertView.getTag();        }        String url = mImgsList[position];        mViewHolder.mImagsView.setTag(url);        displayImage(url , mViewHolder.mImagsView);        return convertView;    }    private static class ViewHolder{        ImageView mImagsView;    }    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        if(scrollState == SCROLL_STATE_IDLE)            loadBitmap(mFirstVisibleItem, mVisibleItemCount);        else            cancelAllDowanTask();    }    @Override    public void onScroll(AbsListView view, int firstVisibleItem,            int visibleItemCount, int totalItemCount) {        mFirstVisibleItem = firstVisibleItem;        mVisibleItemCount = visibleItemCount;        if(isFirstCome && visibleItemCount > 0){            isFirstCome = false;            loadBitmap(mFirstVisibleItem, mVisibleItemCount);        }    }    private void displayImage(String url, ImageView imgView){        Bitmap mCacheBtimap = getBitmapFromCache(url);        if(mCacheBtimap != null)            imgView.setImageBitmap(mCacheBtimap);        else            imgView.setBackgroundResource(android.R.color.holo_orange_dark);    }    private void loadBitmap(int mFirstVisibleItem, int mVisibleItemCount){        for(int i = mFirstVisibleItem ; i < mFirstVisibleItem + mVisibleItemCount ; i++){            String url = mImgsList[i];            // 判断图片是否存在缓存中,如果存在则不下载。            Bitmap bitmap = getBitmapFromCache(url);            if(bitmap != null){                ImageView imgView = (ImageView) mGridView.findViewWithTag(url);                if(imgView != null)                    imgView.setImageBitmap(bitmap);            }else{                //开启异步任务下载图片                DownloadAsyncTask downTask = new DownloadAsyncTask();                mDownloadTastAllList.add(downTask);                downTask.execute(url);            }        }    }    /**     * 通过key值从LruCache中获取缓存对象     *      * @param key     * @return 如果LruCache存在该key则返回缓存的bitmap,否则返回null     */    private Bitmap getBitmapFromCache(String key){        return mLruCache.get(key);    }    /**     * 通过key将Bitmap缓存到LruCache中     *      * @param key     * @param bitmap     */    private void putBitmapToCache(String key, Bitmap bitmap){        if(getBitmapFromCache(key) == null && bitmap != null)            mLruCache.put(key, bitmap);    }    /**     * 清除所有缓存     */    public void clearAllCache(){        if(mLruCache != null){            if(mLruCache.size() > 0)                mLruCache.evictAll();            mLruCache = null;        }    }    /**     * 通过url异步下载图片,下载成功后保存至缓存中,并显示     * @author Rrichard     *     */    class DownloadAsyncTask extends AsyncTask<String,Void,Bitmap>{        private String imgUrl ;        @Override        protected Bitmap doInBackground(String... params) {            imgUrl = params[0];            Bitmap bitmap = getBitmapForUrl(imgUrl);            if(bitmap != null)                putBitmapToCache(imgUrl , bitmap);            return bitmap;        }        @Override        protected void onPostExecute(Bitmap result) {            super.onPostExecute(result);            ImageView mImageView = (ImageView) mGridView.findViewWithTag(imgUrl);            if(mImageView != null && result != null){                mImageView.setImageBitmap(result);                mDownloadTastAllList.remove(this);            }        }    }    /**     * 取消所有下载任务     */    public void cancelAllDowanTask(){        if(mDownloadTastAllList != null && mDownloadTastAllList.size() != 0){            for(DownloadAsyncTask task : mDownloadTastAllList)                task.cancel(true);        }    }    /**     * 通过URL下载图片     *      * @param url     * @return     */    private Bitmap getBitmapForUrl(String url){        Bitmap bitmap = null;        HttpURLConnection connection = null;        try {            URL mUrl = new URL(url);            connection = (HttpURLConnection) mUrl.openConnection();            connection.setConnectTimeout(10 * 1000);            connection.setReadTimeout(10 * 1000);            connection.setDoInput(true);            connection.setDoOutput(true);            connection.connect();            if(connection.getResponseCode() == HttpsURLConnection.HTTP_OK)                bitmap = BitmapFactory.decodeStream(connection.getInputStream());        } catch (MalformedURLException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally{            if(connection != null){                connection.disconnect();                connection = null;            }        }        return bitmap;    }}

效果图用应用宝编辑的,搞得不是很好。不要介意,将就着看

到这里就是一个简单的LruCache图片缓存的使用,但是,在实际开发中我们肯定不能像上面这样使用。因为很明显嘛,上面的代码有很多问题。比如:下载图片时,一个个下载这效率特低了吧!而且很容易出现异常。图片下载下来,图片太大了会出现OOM,因为图片没有压缩采样处理。所以,我们先就图片的处理来进行一下简单的修改。

/**     * 通过URL下载图片     *      * @param url     * @return     */    private Bitmap getBitmapForUrl(String url){        Bitmap bitmap = null;        HttpURLConnection connection = null;        try {            URL mUrl = new URL(url);            connection = (HttpURLConnection) mUrl.openConnection();            connection.setConnectTimeout(10 * 1000);            connection.setReadTimeout(10 * 1000);            connection.setDoInput(true);            connection.setDoOutput(true);            connection.connect();            if(connection.getResponseCode() == HttpsURLConnection.HTTP_OK){                InputStream inputStream = connection.getInputStream();                ByteArrayOutputStream outStream = new ByteArrayOutputStream();                      byte[] buffer = new byte[1024];                      int len = 0;                      while( (len=inputStream.read(buffer)) != -1){                          outStream.write(buffer, 0, len);                      }                      outStream.close();                      inputStream.close();                      byte[] data = outStream.toByteArray();                if(data != null){                    // 进行采样压缩图片                    BitmapFactory.Options options = new BitmapFactory.Options();                    options.inJustDecodeBounds = true;                    BitmapFactory.decodeByteArray(data, 0, data.length , options);                    int height = options.outHeight;                    int width = options.outWidth;                    int inSampleSize = 1;                    if(height > 150 || width > 150){                        int heightSize = Math.round(height / 80);                        int widthSize = Math.round(width / 80);                        inSampleSize = heightSize >= widthSize ? widthSize : heightSize;                    }                    options.inSampleSize = inSampleSize;                    options.inJustDecodeBounds = false;                    bitmap = BitmapFactory.decodeByteArray(data, 0, data.length , options);;                }            }        } catch (MalformedURLException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally{            if(connection != null){                connection.disconnect();                connection = null;            }        }        return bitmap;    }

当然这代码也不是写得很好,只是举个简单的例子。实际开发中肯定不能这样做,得剥离出来,进行优化。所以后面的就留到下一篇博客在写吧!

Demo下载地址:http://download.csdn.net/detail/richardli1228/9296797

1 0
原创粉丝点击