Android网络通信工具Volley

jopen 10年前

请求一个Image

Volley 提供了一下classes 来帮助开发者请求server上的图片。这些类提供的不同的level来处理图片

  • ImageRequest:通过一个图片url可以获取一张bitmap,这个类提供了方便的特性比如说改变图片的大小。他的主要好处事通过Volley的线程schedule老确保图片的编码和调整大小

  • ImageLoader:可以通过URL获取大量的图片。比如要将大量的缩略图放在一个ListView中。ImageLoader提供了一个内存级别的缓存机制,这个就防止了图片的闪烁。同时,ImageLoader还提供了聚合的response,可以同时返回多个response,从而提高了性能。

  • NetworkImageView:建立在ImageLoader之上,在获取远程图片的时候可以完全的取代Imageview。


使用ImageRequest

ImageRequest request = new ImageRequest(url,  new Response.Listener() {      @Override      public void onResponse(Bitmap bitmap) {          mImageView.setImageBitmap(bitmap);      }  }, 0, 0, null,  new Response.ErrorListener() {      public void onErrorResponse(VolleyError error) {          mImageView.setImageResource(R.drawable.image_load_error);      }  });

记得通过一个单类将请求天剑到RequestQueue。

使用ImageLoader和NetworkImageView

可以使用ImageLoader和Network这个对组合来展示多副图片,在xml文件中可以这么写

<com.android.volley.toolbox.NetworkImageView      android:id="@+id/networkImageView"      android:layout_width="150dp"      android:layout_height="170dp"      android:layout_centerHorizontal="true" />

也可以只使用ImageLoader:

ImageLoader mImageLoader;  ImageView mImageView;   // The URL for the image that is being loaded.  private static final String IMAGE_URL =  "http://developer.android.com/images/training/system-ui.png";  ...  mImageView = (ImageView) findViewById(R.id.regularImageView);// Get the ImageLoader through your singleton class.  mImageLoader = MySingleton.getInstance(this).getImageLoader();  mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,  R.drawable.def_image, R.drawable.err_image));

当然也可以将他们两个结合起来使用。

那个为什么要使用单类模式呢。可以参考:

This approach ensures that your app creates single instances of these classes that last the lifetime of your app. The reason that this is important for ImageLoader (the helper class that handles loading and caching images) is that the main function of the in-memory cache is to allow for flickerless rotation. Using a singleton pattern allows the bitmap cache to outlive the activity. If instead you create the ImageLoader in an activity, the ImageLoader would be recreated along with the activity every time the user rotates the device. This would cause flickering.

一个LRU缓存的例子

Volley提供了一个标准的缓存实现通过DiskBasedCache这个类。这个类乐意直接缓存图片到磁盘文件中的一个具体的目录下面。 但是当你使用ImageLoader的是时候你应该实现ImageLoader.ImageCache这个接口。

public class LruBitmapCache extends LruCache<String, Bitmap>      implements ImageCache {    public LruBitmapCache(int maxSize) {      super(maxSize);  }    public LruBitmapCache(Context ctx) {      this(getCacheSize(ctx));  }    @Override  protected int sizeOf(String key, Bitmap value) {      return value.getRowBytes() * value.getHeight();  }    @Override  public Bitmap getBitmap(String url) {      return get(url);  }    @Override  public void putBitmap(String url, Bitmap bitmap) {      put(url, bitmap);  }    // Returns a cache size equal to approximately three screens worth of images.  public static int getCacheSize(Context ctx) {      final DisplayMetrics displayMetrics = ctx.getResources().              getDisplayMetrics();      final int screenWidth = displayMetrics.widthPixels;      final int screenHeight = displayMetrics.heightPixels;      // 4 bytes per pixel      final int screenBytes = screenWidth * screenHeight * 4;        return screenBytes * 3;  }  }

这个是ImageLoader使用那个缓存

RequestQueue mRequestQueue; // assume this exists.  ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache(          LruBitmapCache.getCacheSize()));

请求一个JSON

类说明:

  • JsonArrayRequest:根据URL返回的是一个JsonArray
  • JsonObjectRequest:可以返回一个JsonObject,同时允许将一个JsonObject传激怒去作为请求的body(通过Gson)