LruCache类的使用(内存优化)
来源:互联网 发布:网吧奖励软件 编辑:程序博客网 时间:2024/06/13 10:58
这样做,只能自己写图片加载工具类,完全抛弃了第三方的图片加载框架
知识点:
1)Runtime类(运行时类):Runtime类封装了运行时的环境,每个应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。可以通过getRuntime 方法获取当前Runtime运行时对象的引用,旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控制虚拟机的状态和行为。
Runtime.getRuntime().totalMemory()获取的值是动态的,是虚拟机从系统那里获取的,可以进行内存管理。
2)LruCache类:主要用于内存优化,核心是LinkedHashMap,用Lru算法+数据结构实现,把近期最少使用的数据从缓存中移除,保留使用最频繁的数据(近期最少使用的,使用频率)LruCache以键值对的形式存储数据。
主要用法:构造函数的使用,添加缓存,根据url获取缓存的方法
//1)构造函数要传入一个int类型值,表示缓存的最大值,一般是虚拟机的几分之一。 int maxSize = (int) (Runtime.getRuntime().maxMemory() / 4); LruCache<String, Bitmap> cacheMap = new LruCache(maxSize); //2)添加缓存 cacheMap.put("key", bitmap); //3)根据key获取缓存 Bitmap bit = cacheMap.get("key");
3)BitmapUtils和大多数图片加载框架一样,都是基于内存-文件-网络三级缓存。也就是加载图片的时候首先从内存缓存中取,如果没有再从文件缓存中取,如果文件缓存没有取到,就从网络下载图片并且加入内存和文件缓存。
BitmapUtils内存缓存是如何实现的?BitmapUtils内存缓存的核心类LruMemoryCache,LruMemoryCache代码和v4包的LruCache一样。
4)Executors线程池类的使用:ExecutorService executorService = Executors.newFixedThreadPool(5); 创建一个包含五个线程的线程池,主要是为了重复利用线程。ExecutorService是一个线程池的管理工具。
案例:在ListView中,使用LruCache缓存图片(去掉了sdcard缓存,相当于抄了一遍代码)
Activity中的代码:
package com.crs.demo.ui.lrucache;import android.graphics.Bitmap;import android.os.Bundle;import android.os.Handler;import android.support.v4.util.LruCache;import android.widget.ListView;import com.crs.demo.R;import com.crs.demo.adapter.LruCacheAdapter;import com.crs.demo.base.BaseActivity;import java.util.ArrayList;/** * Created on 2016/10/9. * Author:crs * Description:LruCache的使用 */public class LruCacheActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lrucache); initViews(); } private void initViews() { ArrayList list = new ArrayList<>(); list.add("http://img5.imgtn.bdimg.com/it/u=2296402476,2057547975&fm=21&gp=0.jpg"); list.add("http://img.sdchina.com/news/20100604/c01_2e9c516d-cf8e-468b-a9a5-bc78bc277e71_3.jpg"); list.add("http://p.ishowx.com/uploads/allimg/160823/415-160R3095959.jpg"); ListView lv_test_lru_cache = findView(R.id.lv_test_lru_cache); LruCacheAdapter lruCacheAdapter = new LruCacheAdapter(this, list); lv_test_lru_cache.setAdapter(lruCacheAdapter); }}
adapter中的代码:
package com.crs.demo.adapter;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import com.crs.demo.R;import com.crs.demo.ui.lrucache.BitmapUtil;import java.util.ArrayList;/** * Created on 2016/10/9. * Author:crs * Description:LruCacheAdapter主要用于测试内存优化 */public class LruCacheAdapter extends BaseAdapter { private LayoutInflater mInflater; private ArrayList<String> list; private final BitmapUtil mBitmapUtils; public LruCacheAdapter(Context mContext, ArrayList<String> list) { mInflater = LayoutInflater.from(mContext); this.list = list; mBitmapUtils = new BitmapUtil(mContext); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = mInflater.inflate(R.layout.item_viewpager_lrucache, null); ImageView iv = (ImageView) view.findViewById(R.id.iv_item_viewpager_lrucache); mBitmapUtils.display(iv,list.get(position)); return view; }}BitmapUtil中的代码:
package com.crs.demo.ui.lrucache;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Message;import android.support.v4.util.LruCache;import android.widget.ImageView;import com.crs.demo.utils.ToastUtils;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * Created on 2016/10/9. * Author:crs * Description:封装LruCache的使用 */public class BitmapUtil { private Context mContext; private static final int SUCCESS_LOAD_DATA = 0; private static final int FAILURE_LOAD_DATA = 1; //LruCache实例,用于存储Bitmap private LruCache<String, Bitmap> mLruCache; //线程池管理类 private ExecutorService executorService = Executors.newFixedThreadPool(5); //创建主线程的消息对象 private BitmapUtil.InnerHandler mHandler = new BitmapUtil.InnerHandler(); public BitmapUtil(Context context) { this.mContext = context; //总的可用内存 int mTotalSize = (int) Runtime.getRuntime().totalMemory(); mLruCache = new LruCache<String, Bitmap>(mTotalSize / 8) { @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight(); } }; } public void display(ImageView iv, String url) { Bitmap bitmap = getBitmapFromMemory(url); if (bitmap != null) { iv.setImageBitmap(bitmap); } else { getBitmapFromInternet(iv, url); } } private void getBitmapFromInternet(ImageView iv, String url) { executorService.submit(new BitmapUtil.DownloadImageTask(iv, url)); } private Bitmap getBitmapFromMemory(String url) { return mLruCache.get(url); } //加载网络图片的线程类 private class DownloadImageTask implements Runnable { private String imageUrl; //如何把此ImageView对象传递到Handler中 private ImageView iv; private HttpURLConnection conn; public DownloadImageTask(ImageView iv, String url) { this.imageUrl = url; this.iv = iv; } @Override public void run() { try { URL url = new URL(imageUrl); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(3000); if (conn.getResponseCode() == 200) { InputStream is = conn.getInputStream(); //此时bitmap对象在子线程里面 Bitmap bitmap = BitmapFactory.decodeStream(is); //使用LruCache执行内存缓存 mLruCache.put(imageUrl, bitmap); //封装对象进行传递 BitmapUtil.ImageViewBitmap imageViewBitmap = new BitmapUtil.ImageViewBitmap(); imageViewBitmap.bitmap = bitmap; imageViewBitmap.iv = iv; Message message = mHandler.obtainMessage(SUCCESS_LOAD_DATA, imageViewBitmap); message.sendToTarget(); is.close(); } else { mHandler.sendEmptyMessage(FAILURE_LOAD_DATA); } } catch (Exception e) { e.printStackTrace(); mHandler.sendEmptyMessage(FAILURE_LOAD_DATA); } finally { if (conn != null) { conn.disconnect(); } } } } //传递消息的类 private class InnerHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case SUCCESS_LOAD_DATA: { BitmapUtil.ImageViewBitmap imageViewBitmap = (BitmapUtil.ImageViewBitmap) msg.obj; Bitmap bitmap = imageViewBitmap.bitmap; ImageView iv = imageViewBitmap.iv; iv.setImageBitmap(bitmap); } break; case FAILURE_LOAD_DATA: { ToastUtils.showShort(mContext, "图片加载异常"); } break; } } } //把两者封装成一个对象进行传递 private static class ImageViewBitmap { ImageView iv; Bitmap bitmap; }}
- LruCache类的使用(内存优化)
- Android lrucache 实现与使用(Android内存优化)
- 详解基于LRU缓存的LruCache类及其在Android内存优化中的应用
- Andrid内存优化之你必须知道的核心类LruCache
- android LruCache的使用 (本地缓存+内存缓存)
- LruCache详解之 Android 内存优化
- LruCache详解之 Android 内存优化
- LruCache详解之 Android 内存优化
- LruCache详解之 Android 内存优化
- LruCache详解之Android内存优化
- LruCache详解之 Android 内存优化
- LruCache的使用
- LruCache的使用--pizifusheng
- LruCache(内存缓存)的原理
- 使用lrucache实现图片内存缓存
- 使用LruCache的代码整理
- 缓存LruCache的使用步骤
- Android中使用的LruCache
- Wireshark学习的博客
- Python基本语法
- 知识管理软件之一 有声大屏听说读写
- Android图片缓存之Bitmap详解
- 关于DMA基础知识
- LruCache类的使用(内存优化)
- 我要开始写一些博客了
- 【OpenCV】 大津展之法
- Windowsserver 2003域控直接迁移到2012
- Qt4过渡至Qt5
- 我的算法学习之路
- QT 错误集锦
- Java 多线程(2):ReentrantLock以及lock()、lockInterruptibly()之间的区别
- Cocos2d-x游戏引擎开发[1]----HelloWorld