美文网首页
Android 图片的三级缓存策略,以及大图片的加载

Android 图片的三级缓存策略,以及大图片的加载

作者: 海是倒过来的天_67f2 | 来源:发表于2018-08-07 21:35 被阅读0次

    1.图片的三级缓存策略

    1.内存缓存:优先加载,速度最快

    2.本地缓存:次优先级加载,速度次之,

    3.网络缓存:最后加载,速度由网速决定

    2.内存缓存

    首先创建一个MemoryCacheUtils类,内存缓存一般使用LruChche缓存策略,首先需要或者应用可用的最大内存,然后设置缓存的可用大小,将图片的缓存大小设为最大缓存的1/8或者1/4,应在初始化中调用,因此

    public MemoryCacheUtils(){

        long maxMemory = Runtime.getRuntime().maxMemory();//获取最大内存,一般默认是16MB

        //获取图片字节数

        mLruCache = new LruCache((int)maxMemory/8){

            @Override

            protected int sizeOf(String key, Bitmap value) {

                //获取图片字节数

                int byteCount = value.getRowBytes() * value.getWidth();

                return byteCount;

            }

        };

    }

    内存缓存中对图片的保存和读取十分简单

    //从内存中获取图片

    public Bitmap getBitmapFormMemory(String url){

        return mLruCache.get(url);

    }

    //将图片保存在内存中

    public void saveBitmap2Memory(String url, Bitmap bitmap){

        mLruCache.put(url, bitmap);

    }

    3.本地缓存

    本地缓存首先需要获取SD卡的根目录的路径

    public static final String CACHE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()+"/imagememory/";

    图片的保存

    首先以Url作为关键字对图片进行保存,在保存时需要对Url进行MD5加密,将加密后返回的字符串作为关键字创建文件夹,同时保存图片

    public void saveBitmap2SD(String url, Bitmap bitmap){

        //对文件地址进行MD5加密

        String fileName = null;

        try {

            fileName = MD5Encoder.encode(url);

        } catch (Exception e) {

            e.printStackTrace();

        }

        File file = new File(CACHE_PATH, fileName);

        File parentFile = file.getParentFile();

        if (!parentFile.exists()){

            parentFile.mkdirs();

        }

        try {

            //将图片保存到本地

            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(file));

        } catch (FileNotFoundException e){

            e.printStackTrace();

        }

    }

    图片的读取

    从SD卡中读取图片,首先也需要将传入的Url进行加密并将返回的字符串作为索引,查找对应的文件夹中,通过BitmapFactory.decodeStream获得bitmap

    public Bitmap getImageFormSD(String url){

        //对文件地址进行MD5加密

        String fileName = null;

        try {

            fileName = MD5Encoder.encode(url);

        } catch (Exception e) {

            e.printStackTrace();

        }

        File file = new File(CACHE_PATH, fileName);

        if (file.exists()){

            Bitmap bitmap;

            try {

                bitmap = BitmapFactory.decodeStream(new FileInputStream(file));

                return bitmap;

            } catch (FileNotFoundException e){

                e.printStackTrace();

            }

        }

        return null;

    }

    4.网络缓存图片

    网络缓存图片时需要将网络获得的图片缓存到内存和SD卡中,因此需要在构造方法中初始化内存缓存工具类和SD卡缓存工具类

    public NetCacheUtils(SDcardCacheUtils sDcardCacheUtils, MemoryCacheUtils memoryCacheUtils){

        mSDcardCacheUtils = sDcardCacheUtils;

        mMemoryCacheUtils = memoryCacheUtils;

    }

    从网络中获取图片是一个耗时操作,因此这里采用AsyncTask异步栈的方式实现图片的异步下载,因此就需要自定义一个MyAsyncTask继承与AsyncTask

    class MyAsyncTask extends AsyncTask{

        @Override

        protected Bitmap doInBackground(Object... objects) {

            //拿到传入的iamge

            mImageView = (ImageView)objects[0];

            mUrl = (String)objects[1];

            mImageView.setTag(mUrl);

            Bitmap bitmap = downloadBitmap(mUrl);

            return bitmap;

        }

        @Override

        protected void onPostExecute(Bitmap bitmap) {

            if (bitmap != null){

                String url = (String) mImageView.getTag();

                if (url.equals(mUrl)){

                    mImageView.setImageBitmap(bitmap);

                    mMemoryCacheUtils.saveBitmap2Memory(url, bitmap);

                    mSDcardCacheUtils.saveBitmap2SD(url, bitmap);

                }

            }

        }

    }

    private Bitmap downloadBitmap(String url) {

        HttpURLConnection connection = null;

        try {

            connection = (HttpURLConnection) new URL(url).openConnection();

            connection.setReadTimeout(5000);

            connection.setRequestMethod("GET");

            connection.setConnectTimeout(5000);

            connection.connect();

            int code = connection.getResponseCode();

            if (code == 200){

                InputStream inputStream = connection.getInputStream();

                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                return bitmap;

            }

        } catch (IOException e){

            e.printStackTrace();

        } finally {

            connection.disconnect();

        }

        return null;

    }

    5.大图片的加载

    1.首先需要拿到位图的尺寸后,进行放缩后再加载位图

    BitmapFactory.Options options = new BitmapFactory.Options();

    options.inJustDecodeBounds = true;

    BitmapFactory.decodeStream();

    int imageWidth = options.outWidth;

    int iamgeHight = options.outHeight;

    String imageType = options.outMimeType;

    2.计算inSampleSize

    public static int calculateInSampleZSize(BitmapFactory.Options options, int reqWidth, int reqHeight){

        int width = options.outWidth;

        int height = options.outHeight;

        int inSampleSize = 1;

        if (height>reqHeight || width>reqWidth){

            int halfHeight = height / 2;

            int halfWidth = width / 2;

            while ((halfHeight/inSampleSize)>reqHeight && (halfWidth/inSampleSize)>reqWidth){

                inSampleSize *= 2;

            }

        }

        return inSampleSize;

    }

    3.放缩后再加载小位图

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resid, int reqWidth, int reqHeight){

        BitmapFactory.Options options = new BitmapFactory.Options();

        options.inJustDecodeBounds = true;

        BitmapFactory.decodeResource(res,resid, options);

        options.inSampleSize = calculateInSampleZSize(options,reqWidth, reqHeight);

        options.inJustDecodeBounds= false;

        return BitmapFactory.decodeResource(res,resid,options);

    }

    相关文章

      网友评论

          本文标题:Android 图片的三级缓存策略,以及大图片的加载

          本文链接:https://www.haomeiwen.com/subject/ealzvftx.html