使用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方法是重载了的,你可以选择不设置图片的宽高。这样你就实现了图片缓存 当你第一次加载好了以后下次断开网络一样能显示出来。