文章目录
  1. 1. Volley简介
  2. 2. 基本用法
  3. 3. Request运行线程
  4. 4. 取消Request
  5. 5. 配置RequestQueue
  6. 6. 常用于单例
  7. 7. 两种图片加载方式
  8. 8. 自定义Request

Volley简介

Volley主要用于处理http协议中小文件的下载,不适用与大文件的下载,并且无法暂停只能取消

基本用法

1
2
RequestQueue requestQueue = Volley.newRequestQueue(this);   //新建请求队列
requestQueue.add(request); //队列中加入请求

Request运行线程

一个Request运行在三种线程中: Cache,Worker,Main
Request先在Cache中查找,找不到就从线程池中的某一Worker线程中做网络请求,并解析与存入Cache,最后在主线程回调。

Volley中各线程

取消Request

推荐在onStop()调用Request.cancel(),对于多个请求同时取消,可以用Request.setTag() 添加标志,然后再将添加过相同标志的Request一起取消 RequestQueue.cancelAll( TAG/Filter )

配置RequestQueue

RequestQueue中使用了缓存与网络, 所以可以针对缓存与网络做相应的配置。

1
2
3
4
5
6
7
8
9
10
11
// 配置缓存
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB 大小

// 配置网络,配置如何使用Request, BasicNetwork使用策略模式,HurlStack即是使用HttpUrlConnection作为实现
Network network = new BasicNetwork(new HurlStack());

// Instantiate the RequestQueue with the cache and network.
mRequestQueue = new RequestQueue(cache, network);

// 必须手动start
mRequestQueue.start();

常用于单例

单例中存ImageLoader跟RequestQueue

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
48
49
50
51
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;

private MySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();

mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);

@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}

@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}

public static synchronized MySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new MySingleton(context);
}
return mInstance;
}

public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}

public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}

public ImageLoader getImageLoader() {
return mImageLoader;
}
}

两种图片加载方式

  1. ImageView + ImageRequest :不带缓存(内存上的缓存),与普通Request使用类似
  2. HttpImageView + ImageLoader + ImageLoader.ImageCache:带缓存(内存上的缓存),会先在ImageLoader中的ImageCache查找再到RequestQueue中的DiskBasedCache中查找,前者查找内存,后者查找磁盘
    1
    mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);

ImageLoader配置的ImageCache推荐是用LruBitmapCache,代码如下:

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
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;
}
}

自定义Request

两个重要的类:

  • NetworkResponse 主要封装了响应中的信息
  • HttpHeaderParser 解析NetworkResponse中消息头中的键对

主要实现两个方法

  • Response parseNetworkResponse(NetworkResponse response)
    • 传入的NetworkResonse 的data成员变量为内容,响应头用HttpHeaderParser工具解析
    • 该回调工作在Worker线程,返回Response,Response有两个静态初始化器:
      • 成功返回 Response.success(T, HttpHeaderParser.parseCacheHeaders(response));
      • 失败返回 Response.error(new ParseError(e))
  • deliverResponse(T) 在Main线程中调用,一般调用listenr.onResponse(T)即可
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
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;

/**
* Make a GET request and return a parsed object from JSON.
*
* @param url URL of the request to make
* @param clazz Relevant class object, for Gson's reflection
* @param headers Map of request headers
*/

public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener)
{

super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}

@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}

@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
文章目录
  1. 1. Volley简介
  2. 2. 基本用法
  3. 3. Request运行线程
  4. 4. 取消Request
  5. 5. 配置RequestQueue
  6. 6. 常用于单例
  7. 7. 两种图片加载方式
  8. 8. 自定义Request