android - volley的使用

发表于:,更新于:,By Sally
大纲
  1. 1. Android 网络通信框架 Volley
    1. 1.1. 几个特点
    2. 1.2. 功能
    3. 1.3. 请求包括以下几种对象
  2. 2. volley 的使用
    1. 2.1. 先声明请求队列 RequestQueue
    2. 2.2. 字符数据处理 : StringRequest
      1. 2.2.1. get 方式
      2. 2.2.2. post 方式
    3. 2.3. JSON对象数据处理 : JsonObject
      1. 2.3.1. get 方法
      2. 2.3.2. post 方法
    4. 2.4. volley 和 activity 的关联
  3. 3. 自定义 volley
    1. 3.1. 首先:定义 VolleyInterface 抽象类
    2. 3.2. 接着:定义请求工具类,这里以StringRequest为例
    3. 3.3. 最后:使用自定义volley实现get请求 : stringrequest
  4. 4. 图片缓存
    1. 4.1. ImageRequest 的使用
    2. 4.2. ImageLoader + ImageCache + LruCache :缓存图片

Android 网络通信框架 Volley

几个特点

  • 支持 get post 网络图片 等的高效异步处理请求

  • 可以对请求进行排序

  • 支持网络请求缓存

  • 支持多级别取消请求

  • 与activity生命周期联动

  • 不适合数据的上传和下载(如果需要上传和下载,选用别的,eg:okhttp)

功能

  • 高效的get post方式的数据请求交互

  • 网络图片的加载和缓存

请求包括以下几种对象

  • StringRequest : 不清楚数据的返回类型时,使用stringrequest

  • JsonObjectRequest : 返回的是json对象时,使用jsonobjectrequest

  • JsonArrayRequest : 返回的是json数组时,使用jsonarrayrequest

volley 的使用

先声明请求队列 RequestQueue

  • 所有request 请求都是放到这个队列进行处理,所以我们将这个队列声明在Application里,记得在manifest中配置一下myapplication
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MyApplication extends Application {

public static RequestQueue queues = null;

@Override
public void onCreate() {
super.onCreate();
queues = Volley.newRequestQueue(getApplicationContext());
}

public static RequestQueue getHttpRequestQueue() {
return queues;
}
}

字符数据处理 : StringRequest

get 方式

  • 这里使用了4个参数的方法:请求方式,请求地址,请求成功回调,请求失败回调
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void volley_get_string() {
String url = "http://172.21.170.2:3333/interface/communicate_log/friends?mobilephone=supervisor_17777777777";
StringRequest request = new StringRequest(Method.GET, url, new Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_SHORT).show();
}
});

// 设置tag标签,关闭任务时,会用到
request.setTag("StringRequestGett");

// 将该请求添加到请求队列中
MyApplication.getHttpRequestQueue().add(request);
}

post 方式

  • 参数:请求方式,请求地址,请求成功回调,请求失败回调,重写getParams()方法获得请求参数。
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
private void volley_post_string() {
String url = "http://172.21.170.2:3333/interface/communicate_log/friends?";
StringRequest request = new StringRequest(Method.POST, url, new Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_SHORT).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
// 将参数放到map集合中,并返回,post请求会自己调用
Map<String, String> map = new HashMap<String, String>();
map.put("mobilephone", "supervisor_17777777777");
return map;
}
};

// 设置标签
request.setTag("StringRequestPost");

// 添加到请求队列中
MyApplication.getHttpRequestQueue().add(request);
}

JSON对象数据处理 : JsonObject

get 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void volley_get_jsonobject() {
String url = "http://172.21.170.2:3333/interface/communicate_log/friends?mobilephone=supervisor_17777777777";
JsonObjectRequest request = new JsonObjectRequest(Method.GET, url, new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_SHORT).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_SHORT).show();
}
});
request.setTag("JsonObjectGet");
MyApplication.getHttpRequestQueue().add(request);
}

post 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private void volley_psot_jsonobject() {
String url = "http://172.21.170.2:3333/interface/communicate_log/friends?";
Map<String, String> map = new HashMap<String, String>();
map.put("mobilephone", "supervisor_17777777777");
JSONObject obj = new JSONObject(map);
JsonObjectRequest request = new JsonObjectRequest(Method.POST, url, obj, new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_SHORT).show();
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_SHORT).show();
}
});
request.setTag("JsonObjectPost");
MyApplication.getHttpRequestQueue().add(request);
}

volley 和 activity 的关联

  • 在销毁activity时,取消掉该activity的所有请求
1
2
3
4
5
6
7
@Override
protected void onDestroy() {
super.onDestroy();

// 这里,就是根据上面设置的tag进行取消的,所以tag值要有意义
MyApplication.getHttpRequestQueue().cancelAll("Get");
}

自定义 volley

  • 有时候,我们需要在请求成功时,做些事情;在请求失败时,做些事情;请求多了,每次都写会重复很多。所以就需要自定义volley了

首先:定义 VolleyInterface 抽象类

  • 声明一个有3个参数的构造方法,上下文,成功监听回调,失败监听回调

  • 两个抽象方法: 请求成功方法, 请求失败方法

  • 在这里,可以做一些处理,请求成功了做什么,请求失败了做什么

  • 注意:这里的mListener mErrorListener都是静态的,且这两个对象都是在这个文件中创建和使用,自给自足

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
public abstract class VolleyInterface {

public Context mContext;
public static Listener<String> mListener;
public static ErrorListener mErrorListener;

public VolleyInterface(Context context, Listener listener, ErrorListener errorListener) {
this.mContext = context;
this.mListener = listener;
this.mErrorListener = errorListener;
}

public Listener<String> loadListener() {
mListener = new Listener<String>() {
@Override
public void onResponse(String response) {
onMyLoading(response);

// 请求成功做些什么事
}
};
return mListener;
}

public ErrorListener errorListener() {
mErrorListener = new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onMyError(error);

// 请求失败做些什么事
}
};
return mErrorListener;
}

public abstract void onMyLoading(String result);
public abstract void onMyError(VolleyError error);
}

接着:定义请求工具类,这里以StringRequest为例

  • get方式的参数:上下文,请求地址,tag标签,回调接口

  • post方式的参数:上下文,请求url,tag标签,请求参数params,回调接口

  • 这里记得start一下请求队列

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
public class VolleyRequest {

public static StringRequest stringRequest;

public static Context mContext;

public static void RequestGet(Context context, String url, String tag, VolleyInterface vif) {
MyApplication.getHttpRequestQueue().cancelAll(tag);

stringRequest = new StringRequest(Request.Method.GET, url, vif.loadListener(), vif.errorListener());
stringRequest.setTag("get");

MyApplication.getHttpRequestQueue().add(stringRequest);
MyApplication.getHttpRequestQueue().start();
}

public static void ResuestPost(Context context, String url, String tag, final Map<String, String> params, VolleyInterface vif) {
MyApplication.getHttpRequestQueue().cancelAll(tag);

StringRequest request = new StringRequest(Method.POST, url, vif.loadListener(), vif.errorListener()){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
};

request.setTag("post");
MyApplication.getHttpRequestQueue().add(request);
MyApplication.getHttpRequestQueue().start();
}
}

最后:使用自定义volley实现get请求 : stringrequest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void volley_get() {
String url = "http://172.21.170.2:3333/interface/communicate_log/friends?mobilephone=supervisor_17777777777";
VolleyRequest.RequestGet(this, url, "abcget", new VolleyInterface(this, VolleyInterface.mListener, VolleyInterface.mErrorListener) {
@Override
public void onMyLoading(String result) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}

@Override
public void onMyError(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_SHORT).show();
}
});
}

图片缓存

  • ImageRequest : 加载远程图片

  • ImageCache 单独使用起不到缓存作用,要搭配 LruCache 一起使用

  • ImageCache + ImageView : 图片缓存

  • ImageCache + NetWorkImageView : 图片缓存

ImageRequest 的使用

  • 加载远程图片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void volley_img_request() {
String url = "https://www.baidu.com/img/bdlogo.png";
ImageRequest request = new ImageRequest(url, new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
iv.setImageBitmap(response);
}
}, 0, 0, ImageView.ScaleType.CENTER, Bitmap.Config.RGB_565, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity2.this, error.toString(), Toast.LENGTH_SHORT).show();
}
});

request.setTag("imgRequest");
MyApplication.getHttpRequestQueue().add(request);
}

ImageLoader + ImageCache + LruCache :缓存图片

  • 这里需要用到 ImageLoader 类,该对象接受两个参数:请求队列,imagecache

  • 首先:定义一个ImageCache的子类,BitmapCache

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
public class BitmapCache implements ImageCache {

public LruCache<String, Bitmap> cache;

//默认缓存大小10m
public int max = 10*1024*1024;

public BitmapCache() {
cache = new LruCache<String, Bitmap>(max){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
};
}

// 返回缓存中的图片
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}

// 将图片放入缓存
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
}
  • 接着:获取并显示图片,使用 imageview
1
2
3
4
5
6
7
8
private void volley_img_loader() {
String url = "https://www.baidu.com/img/bdlogo.png";
ImageLoader loader = new ImageLoader(MyApplication.getHttpRequestQueue(), new BitmapCache());

// 参数: 显示图片的控件,默认图片,请求失败显示图片
ImageListener listener = ImageLoader.getImageListener(iv, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
loader.get(url, listener);
}
  • 接着:获取并显示图片,使用 networkimageView
1
2
3
4
5
6
7
private void volley_img_network() {
String url = "https://www.baidu.com/img/bdlogo.png";
ImageLoader loader = new ImageLoader(MyApplication.getHttpRequestQueue(), new BitmapCache());
iv_net.setDefaultImageResId(R.mipmap.ic_launcher);
iv_net.setErrorImageResId(R.mipmap.ic_launcher);
iv_net.setImageUrl(url, loader);
}