在应用程序开发中图片下载是非常常见的操作,Volley提供了不同的图片下载方式。Volley也提供了透明的图片缓存,也可以灵活的使用自己的图片缓存。
Volley使用ImageRequest加载
和其他的Requst类型一样,它以URL作为参数然后返回Bitmap对象到主线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ImageRequest imgRequest = new ImageRequest(url, new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap response) { mImageView.setImageBitmap(response); } }, 0, 0, Bitmap.Config.ARGB_8888, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { mImageView.setImageResource(R.drawable.error); } }); mVolleyQueue.add(imgRequest); |
第二,三个参数分别表示图片的maxWidth和maxHeight,第四个参数用来指定图片的质量,然后ImageRequest会通过这几个参数来解析图片,调整图片的质量等操作
ImageRequest源码
下面的代码主要是按照比例压缩图片,保障图片不失真。然后讲Bitmap返回到主线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
private Response doParse(NetworkResponse response) { byte[] data = response.data; BitmapFactory.Options decodeOptions = new BitmapFactory.Options(); Bitmap bitmap = null; if (mMaxWidth == 0 && mMaxHeight == 0) { decodeOptions.inPreferredConfig = mDecodeConfig; bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions); } else { // 如果需要调整图片的大小,首先需要得到图片的边缘,包括获取真实宽高 decodeOptions.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions); int actualWidth = decodeOptions.outWidth; int actualHeight = decodeOptions.outHeight; //然后计算出我们期望的尺寸,为了避免图片长宽比例失调,会用实际宽高来计算比例 int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight, actualWidth, actualHeight); int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth, actualHeight, actualWidth); // 计算出最佳的调整比例 decodeOptions.inJustDecodeBounds = false; // TODO(ficus): Do we need this or is it okay since API 8 doesn't support it? // decodeOptions.inPreferQualityOverSpeed = PREFER_QUALITY_OVER_SPEED; decodeOptions.inSampleSize = findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight); Bitmap tempBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions); // If necessary, scale down to the maximal acceptable size. if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth || tempBitmap.getHeight() > desiredHeight)) { bitmap = Bitmap.createScaledBitmap(tempBitmap, desiredWidth, desiredHeight, true); tempBitmap.recycle(); } else { bitmap = tempBitmap; } } if (bitmap == null) { return Response.error(new ParseError(response)); } else { return Response.success(bitmap, HttpHeaderParser.parseCacheHeaders(response)); } } |
ImageLoader加载图片
ImageLoader提供了默认的监听接口实现,可以设置默认加载图和错误加载图,初始化ImageLoader需要传入一个RequstQueue对象。
1 2 3 4 5 6 7 8 9 10 11 |
int max_cache_size = 1000000; mImageLoader = new ImageLoader(mVolleyQueue, new DiskBitmapCache(getCacheDir(),max_cache_size)); //Memorycache is always faster than DiskCache. Check it our for yourself. //mImageLoader = new ImageLoader(mVolleyQueue, new BitmapCache(max_cache_size)); mImageLoader.get(URL, ImageLoader.getImageListener(mImageView, R.drawable.flickr, android.R.drawable.ic_dialog_alert, //根据自定义图片宽高来缩放图片 50,50); |
总结
以上两种方法都可以通过Volley加载图片,但是各有利弊,通过ImageRequest设置自定义的监听接口更加灵活,可以对图片灵活处理,你甚至可以自定义ImageRequset,通过ImageLoader加载图片更加简单,但是失去了一定的灵活性。