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
- Android LruCache图片缓存使用(二)
- android 图片缓存LruCache(二)
- Android LruCache图片缓存使用(一)
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- Android使用 LruCache 缓存图片
- stm32 ds18b20 寄存器设置问题!
- ubuntu中netbean ide中文乱码
- iOS 给UIWebView添加头视图和尾视图
- 前台进程、可见进程、服务进程、后台进程、空进程
- memcpy函数
- Android LruCache图片缓存使用(二)
- C++实现进制转换(十进制转十六进制)
- Java基础---IO流(上)
- 安卓版本更新
- 杭电1491 Octorber 21st
- JAVA RMI远程调用demo
- 线程池分析与使用
- 关于在js中关闭浏览器页面的问题
- Javascript高级程序设计 第八章 --- DOM