zoukankan      html  css  js  c++  java
  • android 项目学习随笔十八(三级缓存)

    xUtils的BitmapUtils模块用的就是三级缓存,在项目中尽量还是应用BitmapUtils

    三级缓存(机制)

    import com.itheima.zhsh66.R;
    
    import android.graphics.Bitmap;
    import android.widget.ImageView;
    
    /**
     * 三级缓存工具类
     * 
     */
    public class MyBitmapUtils {
    
        // 网络缓存工具类
        private NetCacheUtils mNetUtils;
        // 本地缓存工具类
        private LocalCacheUtils mLocalUtils;
        // 内存缓存工具类
        private MemoryCacheUtils mMemoryUtils;
    
        public MyBitmapUtils() {
            mMemoryUtils = new MemoryCacheUtils();
            mLocalUtils = new LocalCacheUtils();
            mNetUtils = new NetCacheUtils(mLocalUtils, mMemoryUtils);
        }
    
        public void display(ImageView imageView, String url) {
            // 设置默认加载图片
            imageView.setImageResource(R.drawable.news_pic_default);
    
            // 先从内存缓存加载
            Bitmap bitmap = mMemoryUtils.getBitmapFromMemory(url);
            if (bitmap != null) {
                imageView.setImageBitmap(bitmap);
                System.out.println("从内存读取图片啦...");
                return;
            }
    
            // 再从本地缓存加载
            bitmap = mLocalUtils.getBitmapFromLocal(url);
            if (bitmap != null) {
                imageView.setImageBitmap(bitmap);
                System.out.println("从本地读取图片啦...");
                // 给内存设置图片
                mMemoryUtils.setBitmapToMemory(url, bitmap);
                return;
            }
    
            // 从网络缓存加载
            mNetUtils.getBitmapFromNet(imageView, url);
        }
    
    }
    MyBitmapUtils

      

    1、内存缓存

    import android.graphics.Bitmap;
    import android.support.v4.util.LruCache;
    
    /**
     * 内存缓存工具类
     * 
     */
    public class MemoryCacheUtils {
    
        // private HashMap<String, SoftReference<Bitmap>> mMemroyCache = new
        // HashMap<String, SoftReference<Bitmap>>();
        // Android 2.3 (API Level
        // 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠,建议用LruCache
        private LruCache<String, Bitmap> mCache;
    
        public MemoryCacheUtils() {
            int maxMemory = (int) Runtime.getRuntime().maxMemory();// 获取虚拟机分配的最大内存
                                                                    // 16M
            // LRU 最近最少使用, 通过控制内存不要超过最大值(由开发者指定), 来解决内存溢出
            mCache = new LruCache<String, Bitmap>(maxMemory / 8) {
                @Override
                protected int sizeOf(String key, Bitmap value) {
                    // 计算一个bitmap的大小
                    int size = value.getRowBytes() * value.getHeight();// 每一行的字节数乘以高度
                    return size;
                }
            };
        }
    
        public Bitmap getBitmapFromMemory(String url) {
            // SoftReference<Bitmap> softReference = mMemroyCache.get(url);
            // if (softReference != null) {
            // Bitmap bitmap = softReference.get();
            // return bitmap;
            // }
            return mCache.get(url);
        }
    
        public void setBitmapToMemory(String url, Bitmap bitmap) {
            // SoftReference<Bitmap> soft = new SoftReference<Bitmap>(bitmap);
            // mMemroyCache.put(url, soft);
            mCache.put(url, bitmap);
        }
    
    }
    MemoryCacheUtils

    2、本地缓存

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    import com.itheima.zhsh66.utils.MD5Encoder;
    
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.CompressFormat;
    import android.graphics.BitmapFactory;
    import android.os.Environment;
    
    /**
     * 本地缓存工具类
     * 
     */
    public class LocalCacheUtils {
    
        // 图片缓存的文件夹
        public static final String DIR_PATH = Environment
                .getExternalStorageDirectory().getAbsolutePath()
                + "/bitmap_cache66";
    
        public Bitmap getBitmapFromLocal(String url) {
            try {
                File file = new File(DIR_PATH, MD5Encoder.encode(url));
    
                if (file.exists()) {
                    Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(
                            file));
                    return bitmap;
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public void setBitmapToLocal(Bitmap bitmap, String url) {
            File dirFile = new File(DIR_PATH);
    
            // 创建文件夹
            if (!dirFile.exists() || !dirFile.isDirectory()) {
                dirFile.mkdirs();
            }
    
            try {
                File file = new File(DIR_PATH, MD5Encoder.encode(url));
                // 将图片压缩保存在本地,参1:压缩格式;参2:压缩质量(0-100);参3:输出流
                bitmap.compress(CompressFormat.JPEG, 100,
                        new FileOutputStream(file));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    LocalCacheUtils

    3、网络缓存

    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.AsyncTask;
    import android.widget.ImageView;
    
    /**
     * 网络缓存
     * 
     */
    public class NetCacheUtils {
    
        private LocalCacheUtils mLocalUtils;
        private MemoryCacheUtils mMemoryUtils;
    
        public NetCacheUtils(LocalCacheUtils localUtils,
                MemoryCacheUtils memoryUtils) {
            mLocalUtils = localUtils;
            mMemoryUtils = memoryUtils;
        }
    
        public void getBitmapFromNet(ImageView imageView, String url) {
            BitmapTask task = new BitmapTask();
            task.execute(imageView, url);
        }
    
        /**
         * AsyncTask是线程池+handler的封装 第一个泛型: 传参的参数类型类型(和doInBackground一致) 第二个泛型:
         * 更新进度的参数类型(和onProgressUpdate一致) 第三个泛型: 返回结果的参数类型(和onPostExecute一致,
         * 和doInBackground返回类型一致)
         */
        class BitmapTask extends AsyncTask<Object, Integer, Bitmap> {
    
            private ImageView mImageView;
            private String url;
    
            // 主线程运行, 预加载
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }
    
            // 子线程运行, 异步加载逻辑在此方法中处理
            @Override
            protected Bitmap doInBackground(Object... params) {
                mImageView = (ImageView) params[0];
                url = (String) params[1];
                mImageView.setTag(url);// 将imageView和url绑定在一起
                // publishProgress(values)//通知进度
    
                // 下载图片
                return download(url);
            }
    
            // 主线程运行, 更新进度
            @Override
            protected void onProgressUpdate(Integer... values) {
                super.onProgressUpdate(values);
            }
    
            // 主线程运行, 更新主界面
            @Override
            protected void onPostExecute(Bitmap result) {
                if (result != null) {
                    // 判断当前图片是否就是imageView要的图片, 防止listview重用导致的图片错乱的情况出现
                    String bindUrl = (String) mImageView.getTag();
                    if (bindUrl.equals(url)) {
                        // 给imageView设置图片
                        mImageView.setImageBitmap(result);
                        System.out.println("网络下载图片成功!");
    
                        // 将图片保存在本地
                        mLocalUtils.setBitmapToLocal(result, url);
    
                        // 将图片保存在内存
                        mMemoryUtils.setBitmapToMemory(url, result);
                    }
                }
            }
    
        }
    
        /**
         * 下载图片
         * 
         * @param url
         */
        public Bitmap download(String url) {
            HttpURLConnection conn = null;
            try {
                conn = (HttpURLConnection) (new URL(url).openConnection());
    
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                conn.setRequestMethod("GET");
    
                conn.connect();
    
                int responseCode = conn.getResponseCode();
                if (responseCode == 200) {
                    InputStream in = conn.getInputStream();
                    // 将流转化为bitmap对象
                    Bitmap bitmap = BitmapFactory.decodeStream(in);
                    return bitmap;
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
    
            return null;
        }
    
    }
    NetCacheUtils

    AsyncTask是线程池+handler的封装 第一个泛型: 传参的参数类型类型(和doInBackground一致) 第二个泛型:
    更新进度的参数类型(和onProgressUpdate一致) 第三个泛型: 返回结果的参数类型(和onPostExecute一致,
    和doInBackground返回类型一致)

    private HashMap<String, SoftReference<Bitmap>> mMemroyCache = new HashMap<String, SoftReference<Bitmap>>();

    Android 2.3 (API Level9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠,建议用LruCache

  • 相关阅读:
    关于FileUpload控件的二种用法,你都懂吗?
    Application全局对象 实现统计当前在线人数和总访问次数
    使用COOKIE对像实现保存用户基本信息(结合Session),ASP.Net实现用户登录全过程
    递规篇历路径之 使用正则过滤( 将符合正则的名称用另种正则格式替换掉 )某个路径下的所有文件或文件夹的完整路径
    小偷程序之网页分块筛选
    c#中的socket编程基础
    ASP.Net中的一些基础家常事
    PHP数组
    Effective C++总结
    构造函数、析构函数、虚函数可否内联,有何意义
  • 原文地址:https://www.cnblogs.com/ecollab/p/6061753.html
Copyright © 2011-2022 走看看