Android 加载网络图片并做缓存

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33023933/article/details/77575204
                                                

                             使用Volley获取网络图片,并作本地缓存

          

               Volley是谷歌公司提供的一个框架,主要用于网络请求和图片加载的功能,今天一个初入Android不久的朋友问到我关于加载网络图片怎么做边整理了一下做个记录。

               获取网络图片有多重方法这里主要讲两种:

                      第一种是ImageRequest没做缓存,

                      第二种是ImageLoader毕竟就这两种常用。



第一种是适用于需要实时更新的图片:

              和网络请求类似:

             第一步都是创建请求队列

             第二步创建ImageRequest对象

             第三步将imagerequst对象加入请求队列中

直接上代码:

       

/**
 * @param  context   上下文对象
 * @param  url       网络图片地址
 * @param  singleImg  需要显示的imageview
 */
private void showPicByVolleyRequest(Context context, String url,final ImageView singleImg){
    RequestQueue mQueue = Volley.newRequestQueue(context);
    ImageRequest imageRequest = new ImageRequest(url,
            new Response.Listener<Bitmap>() {
                @Override
                public void onResponse(Bitmap bitmap) {
                    // TODO Auto-generated method stub
                    singleImg.setImageBitmap(bitmap);
                }
            }, 300, 200, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError e) {
            e.printStackTrace();
        }
    });
    mQueue.add(imageRequest);
}
     

第二种是适用于需要实时更新的图片:

              和网络请求类似:

             第一步都是创建请求队列

             第二步创建ImageLoader对象

             第三步通过imageloader展示图片


       其中为了缓存图片我们需要自己去继承 ImageCache这个类并在里面设置缓存参数


   先上实现了ImageCache的类,里面对参数进行了详细的描述:

package com.example.contentprovide;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.text.TextUtils;
import android.util.LruCache;

import com.android.volley.toolbox.ImageLoader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by Administrator on 2017/8/25.
 */

public class BitmapCache implements ImageLoader.ImageCache {

    private LruCache<String, Bitmap> mCache;

    public BitmapCache() {
        int maxSize = 10 * 1024 * 1024;
        mCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };
    }

    /**
     * 先从缓存中找,有则返回图片,没有则从网络获取 
     */
    @Override
    public Bitmap getBitmap(String url) {
        /**
         * 先从缓存中找,有则返回,没有则返回null 
         */
        Bitmap bitmap = mCache.get(url);

        if (bitmap == null) {
            String fileName = url.substring(url.lastIndexOf("/") + 1);
            /**
             * 如果为null,则缓存中没有,从本地SD卡缓存中找 
             */
            File cacheDir = new File(getSDPath());
            File[] cacheFiles = cacheDir.listFiles();
            if (cacheFiles != null) {
                int i = 0;
                for (; i < cacheFiles.length; i++) {
                    if (TextUtils.equals(fileName, cacheFiles[i].getName()))
                        break;
                }
                /**
                 * 若找到则返回bitmap否则返回null 
                 */
                if (i < cacheFiles.length) {
                    bitmap = getSDBitmap(getSDPath() + "/"
                            + fileName);
                    /**
                     * 将从SD卡中获取的bitmap放入缓存中 
                     */
                    mCache.put(url, bitmap);
                }
            }
        }
        return bitmap;
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        /**
         * 放入缓存中 
         */
        mCache.put(url, bitmap);
        /**
         * 存到本地SD中 
         */
        putSDBitmap(url.substring(url.lastIndexOf("/") + 1), bitmap);
    }

    /**
     * 从本地SD卡中获取图片 
     *
     * @param imgPath
     *            图片路径 
     * @return 图片的Bitmap
     */
    private Bitmap getSDBitmap(String imgPath) {
        Bitmap bm = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        /**
         * 设置临时缓存大小 
         */
        options.inTempStorage = new byte[1024 * 1024];
        /**
         * 通过设置Options.inPreferredConfig值来降低内存消耗: 默认为ARGB_8888: 每个像素4字节. 共32位。 
         * Alpha_8: 只保存透明度,共8位,1字节。 ARGB_4444: 共16位,2字节。 RGB_565:共16位,2字节 
         */
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        /**
         * inPurgeable:设置为True,则使用BitmapFactory创建的Bitmap用于存储Pixel的内存空间, 
         * 在系统内存不足时可以被回收,当应用需要再次访问该Bitmap的Pixel时,系统会再次调用BitmapFactory 
         * 的decode方法重新生成Bitmap的Pixel数组。 设置为False时,表示不能被回收。 
         */
        options.inPurgeable = true;
        options.inInputShareable = true;
        /**
         * 设置decode时的缩放比例。 
         */
        options.inSampleSize = 1;
        bm = BitmapFactory.decodeFile(imgPath, options);
        return bm;
    }
    /**
     *获取sd卡的的路径
     ***/
    public String getSDPath(){
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState()
                .equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在  
        if (sdCardExist)
        {
            sdDir = Environment.getExternalStorageDirectory();//获取跟目录  
        }
        return sdDir.toString();
    }
    /**
     * 将图片保存到本地的SD卡中 
     *
     * @param fileName
     * @param bitmap
     */
    private void putSDBitmap(final String fileName, final Bitmap bitmap) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                File cacheDir = new File(getSDPath());
                if (!cacheDir.exists())
                    cacheDir.mkdirs();
                File cacheFile = new File(getSDPath() + "/"
                        + fileName);
                if (!cacheFile.exists()) {
                    try {
                        cacheFile.createNewFile();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                FileOutputStream fos;
                try {
                    fos = new FileOutputStream(cacheFile);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                    fos.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}


 实现了缓存的了并配置好了参数就该展示我们的网络图片了:

 

 /**
     * @param  context   上下文对象
     * @param  url       网络图片地址
     * @param  singleImg  需要显示的imageview
     */
    private void showPicByVolleyImageLoader(Context context, String url,final ImageView singleImg){
        RequestQueue mQueue = Volley.newRequestQueue(context);
        ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
//        第一个参数指定用于显示图片的ImageView控件,
//        第二个参数指定加载图片的过程中显示的图片,
//        第三个参数指定加载图片失败的情况下显示的图
        ImageLoader.ImageListener listener = ImageLoader.getImageListener(singleImg,
                R.mipmap.ic_launcher,  R.mipmap.ic_launcher);
        imageLoader.get(url, listener);
         //后面的两个参数表示图片大小
        imageLoader.get(url,listener, 200, 200);

    }

  最后的get方法是重载了的,你可以选择不设置图片的宽高。这样你就实现了图片缓存 当你第一次加载好了以后下次断开网络一样能显示出来。


















阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页