博客将按照下面的步骤介绍Volley的重新封装:
1.OkHttp3的关于Volley的HttpStack实现
2.HttpRequest的实现和HttpListener回调监听的封装
3.Volley原始的Request的Wrap
4.各种方式的请求的重新实现
5.统一请求的实现
6.使用
所需依赖:
compile 'com.android.volley:volley:1.0.0'
compile 'com.squareup.okio:okio:1.7.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.google.code.gson:gson:2.6.2'
一、OkHttp3Stack的关于Volley的实现
这个是应该是比较简单的,关于OkHttp3Stack的实现在github上面有实现,本博客里面的实现在我的Github上面。
由于代码比较长,而且这个也不是这篇博客的重点,大家需要的话可以去我的Github查看。
二、HttpRequest的实现和HttpListener回调监听的封装
2.1.HttpRequest的实现
通过查看Volley的源代码我们会发现,Volley的Request的构造方法是这样写的:
public Request(int method, String url, Response.ErrorListener listener)
请求的参数有一些通过构造方法传递,而另外一些参数是通过Request里面的很多的get方法得到的,比如post请求的时候的参数是通过Request类里面的getParams()实现的,而我们需要做的就是如果需要post请求,那么就重写请求类,覆盖里面的getParams方法。
protected Map<String, String> getParams() throws AuthFailureError {
return null;
}
会发现这样并不利于统一的调度,那其实在构造一个请求的时候,参数是不固定的,而且有的需要,有的不需要,这个时候,我们可以通过Builder模式来构造请求,可以进行如下的封装:
package com.yong.volleyok;
/**
* <b>Project:</b> com.yong.volleyok <br>
* <b>Create Date:</b> 2016/4/22 <br>
* <b>Author:</b> qingyong <br>
* <b>Description:</b> 请求的封装,使用Builder模式进行构建 <br>
*/
public class HttpRequest {
private Builder mBuilder;
private HttpRequest(Builder builder) {
this.mBuilder = builder;
}
public Map<String, String> getHeaders() {
return mBuilder.headMaps;
}
public int getMethod() {
return mBuilder.method;
}
public Map<String, String> getParams() {
return mBuilder.params;
}
public Request.Priority getPriority() {
return mBuilder.priority;
}
public String getContentType() {
return mBuilder.contentType;
}
public String getParamsEncodeing() {
return mBuilder.paramsEncodeing;
}
public RetryPolicy getRetryPolicy() {
return mBuilder.retryPolicy;
}
public String getUrl() {
return mBuilder.url;
}
public static final class Builder {
String paramsEncodeing = "UTF-8";
String url;
int method = Request.Method.GET;
Request.Priority priority = Request.Priority.NORMAL;
String contentType = "application/x-www-form-urlencoded; charset=utf-8";
Map<String, String> headMaps = new HashMap<>();
Map<String, String> params = new HashMap<>();
RetryPolicy retryPolicy = new DefaultRetryPolicy(10000, 2, 1.0F);
public Builder(String url) {
this.url = url;
}
/**
* 增加 Http 头信息
*
* @param key key
* @param value value
* @return
*/
public Builder addHeader(String key, String value) {
this.headMaps.put(key, value);
return this;
}
/**
* 增加 Http 头信息
*
* @param headers
* @return
*/
public Builder addheader(Map<String, String> headers) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
this.headMaps.put(entry.getKey(), entry.getValue());
}
return this;
}
/**
* 设置 Http 请求方法
*
* @param method {@link Request.Method}
* @return
*/
public Builder setMethod(int method) {
this.method = method;
return this;
}
/**
* 增加请求参数
*
* @param key key
* @param value value
* @return
*/
public Builder addParam(String key, Object value) {
this.params.put(key, String.valueOf(value));
return this;
}
/**
* 增加请求参数
*
* @param params map<string, object>
* @return
*/
public Builder addParam(Map<String, Object> params) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
this.params.put(entry.getKey(), String.valueOf(entry.getValue()));
}
return this;
}
/**
* 设置请求优先级
*
* @param priority {@link Request.Priority}
* @return
*/
public Builder setPriority(Request.Priority priority) {
this.priority = priority;
return this;
}
/**
* 设置文本类型
*
* @param contentType
* @return
*/
public Builder setContentType(String contentType) {
this.contentType = contentType;
return this;
}
/**
* 设置超时以及重连次数
*
* @param initialTimeoutMs 超时时间
* @param maxNumRetries 重连次数
* @param backoffMultiplier
* @return
*/
public Builder setRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) {
this.retryPolicy = new DefaultRetryPolicy(initialTimeoutMs, maxNumRetries, backoffMultiplier);
return this;
}
/**
* 构建 HttpRequest
*
* @return
*/
public HttpRequest build() {
return new HttpRequest(this);
}
}
}
- 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
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
我们构造这样的一个请求的类,然后在请求的时候可以通过这个类,去构建请求的时候需要的一些参数。这个类很简单就不用详细的讲解了。具体的怎么使用这个类去构造请求,我们会在Wrap Volley的Request的时候详细的说明。
2.2.HttpListener的封装
其实就是回调的封装,在Volley里面是使用了两个接口来做的,这里统一成一个接口。
package com.yong.volleyok;
/**
* <b>Project:</b> com.yong.volleyok <br>
* <b>Create Date:</b> 2016/4/22 <br>
* <b>Author:</b> qingyong <br>
* <b>Description:</b> 回调响应 <br>
*/
public interface HttpListener<T> {
/**
* 服务器响应成功
*
* @param result 响应的理想数据。
*/
void onSuccess(T result);
/**
* 网络交互过程中发生错误
*
* @param error {@link VolleyError}
*/
void onError(VolleyError error);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
将成功和失败的回调封装到一个方法里面了。
三、Request的Wrap
为了以后能更好的升级的考虑,我们最好是不采用直接改源代码的方式,所以我们只能对原始的请求类Request类进行Wrap,然后我们自定义请求类继承这个Wrap的类。先贴代码,然后讲解。
package com.yong.volleyok.request;
/**
* <b>Project:</b> com.yong.volleyok <br>
* <b>Create Date:</b> 2016/4/22 <br>
* <b>Author:</b> qingyong <br>
* <b>Description:</b> 原始请求的包装 <br>
*/
public abstract class RequestWrapper<T> extends com.android.volley.Request<T> {
/**
* 请求
*/
protected HttpRequest mHttpRequest;
/**
* 结果
*/
protected HttpListener<T> mHttpListener;
public RequestWrapper(HttpRequest httpRequest, HttpListener<T> listener) {
super(httpRequest.getMethod(), httpRequest.getUrl(), null);
this.mHttpRequest = httpRequest;
this.mHttpListener = listener;
}
/**
* 得到url,这里get方法作处理,把参数都拼接上去
*
* @return
*/
@Override
public String getUrl() {
try {
if (getMethod() == Method.GET &&
(getParams() != null && getParams().size() != 0)) {
String encodedParams = getEncodedUrlParams();
String extra = "";
if (encodedParams != null && encodedParams.length() > 0) {
if (!mHttpRequest.getUrl().endsWith("?")) {
extra += "?";
}
extra += encodedParams;
}
return mHttpRequest.getUrl() + extra;
}
} catch (AuthFailureError e) {
}
return mHttpRequest.getUrl();
}
/**
* 拼接get请求的参数的拼接
*
* @return
* @throws AuthFailureError
*/
public String getEncodedUrlParams() throws AuthFailureError {
StringBuilder encodedParams = new StringBuilder();
String paramsEncoding = getParamsEncoding();
Map<String, String> params = getParams();
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
if (null == entry.getValue()) {
continue;
}
encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
encodedParams.append('&');
}
return encodedParams.toString();
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
/**
* 得到请求头
*
* @return
* @throws AuthFailureError
*/
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return mHttpRequest.getHeaders();
}
/**
* 请求参数
*
* @return
* @throws AuthFailureError
*/
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return mHttpRequest.getParams();
}
/**
* 请求的ContentType
*
* @return
*/
@Override
public String getBodyContentType() {
return mHttpRequest.getContentType();
}
/**
* 请求的优先级,这里RequestQueue里面会根据这个把请求进行排序
*
* @return
*/
@Override
public Priority getPriority() {
return mHttpRequest.getPriority();
}
/**
* 设置请求时长,请求失败之后的次数
*
* @return
*/
@Override
public RetryPolicy getRetryPolicy() {
return mHttpRequest.getRetryPolicy();
}
/**
* 请求成功
*
* @param response The parsed response returned by
*/
@Override
protected void deliverResponse(T response) {
if (mHttpListener != null) {
mHttpListener.onSuccess(response);
}
}
/**
* 请求失败
*
* @param error Error details
*/
@Override
public void deliverError(VolleyError error) {
if (mHttpListener != null) {
mHttpListener.onError(error);
}
}
}
- 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
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
这里最重要的就是这个类了,下面详细的说一下,封装的过程:
我们在前面定义了HttpRequest和HttpListener类就是为了在这里使用,在构造方法里面把这两个传递进来,然后请求需要的参数通过HttpRequest的一系列的get方法获取,请求最终的回调通过HttpListener传递出去。
首先来看HttpListener的最终的两个回调的方法:
@Override
protected void deliverResponse(T response) {
if (mHttpListener != null) {
mHttpListener.onSuccess(response);
}
}
@Override
public void deliverError(VolleyError error) {
if (mHttpListener != null) {
mHttpListener.onError(error);
}
}
这两个方法一个是请求成功的方法,另外一个是请求失败的方法,我们通过HttpListener把最后的结果抛出去,这里可以统一实现,不需要子请求类再去实现了。
再看其余的一些方法,getUrl方法是请求的url,但是我们在封装请求的时候不管是get还是post都是把参数放置getParams方法里面返回的,get请求是直接使用url拼接参数的,所以需要对这个方法进行重写,这样,才能保证get请求能有参数。
getHeaders是请求头,这里直接使用HttpRequest获取到。
getParams时请求的参数,也是直接通过HttpRequest拿到。
其余的方法都是大同小异,总体来说这个封装也比较简单的。
四、各种方式的请求的重新实现
上面对Request进行了重新的封装之后,我们只需要继承RequestWrapper即可,并且,需要我们实现的方法也只有一个了,parseNetworkResponse。由于我们队Request进行了封装,所以Volley自己带的几个请求,如JsonRequest,StringRequest等,都需要重写,继承RequestWrapper,但是,经过我们的封装,重写不会很麻烦。
这里只举两个例子,一个ByteRequest:
package com.yong.volleyok.request;
/**
* <b>Project:</b> com.yong.volleyok.request <br>
* <b>Create Date:</b> 2016/4/23 <br>
* <b>Author:</b> qingyong <br>
* <b>Description:</b> Byte Request <br>
*/
public class ByteRequest extends RequestWrapper<byte[]> {
public ByteRequest(HttpRequest httpRequest, HttpListener<byte[]> listener) {
super(httpRequest, listener);
}
@Override
protected Response<byte[]> parseNetworkResponse(NetworkResponse response) {
return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
可以看到经过我们的封装之后,实现变得非常简单了。
GsonRequest:
package com.yong.volleyok.request;
/**
* <b>Project:</b> com.yong.volleyok.request <br>
* <b>Create Date:</b> 2016/4/23 <br>
* <b>Author:</b> qingyong <br>
* <b>Description:</b> Gson Request <br>
*/
public class GsonRequest<T> extends RequestWrapper<T> {
private static Gson mGson = new Gson();
private Class<T> mClass;
private TypeToken<T> mTypeToken;
public GsonRequest(Class<T> tClass, HttpRequest httpRequest, HttpListener<T> listener) {
this(tClass, null, httpRequest, listener);
}
public GsonRequest(Class<T> tClass, TypeToken<T> typeToken,
HttpRequest httpRequest, HttpListener<T> listener) {
super(httpRequest, listener);
mClass = tClass;
mTypeToken = typeToken;
}
@SuppressWarnings("unchecked")
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data, HttpHeaderParser.parseCharset(response.headers, getParamsEncoding()));
if (mTypeToken == null) {
return Response.success(
mGson.fromJson(json, mClass), HttpHeaderParser.parseCacheHeaders(response));
} else {
return (Response<T>) Response.success(
mGson.fromJson(json, mTypeToken.getType()), HttpHeaderParser.parseCacheHeaders(response));
}
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
- 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
这里只贴出这两个方法,还有的方法可以看github。
五、统一请求的实现
请求都封装好了,现在只有调用了,针对封装的6种请求可以封装一个接口。
package com.yong.volleyok;
/**
* <b>Project:</b> com.yong.volleyok <br>
* <b>Create Date:</b> 2016/4/23 <br>
* <b>Author:</b> qingyong <br>
* <b>Description:</b> 请求 <br>
*/
public interface IHttpClient {
/**
* byte请求
*/
Request byteRequest(HttpRequest httpRequest, HttpListener<byte[]> listener, Object tag);
/**
* String请求
*/
Request stringRequest(HttpRequest httpRequest, HttpListener<String> listener, Object tag);
/**
* gzip请求
*/
Request gZipRequest(HttpRequest httpRequest, HttpListener<String> listener, Object tag);
/**
* JsonObject请求
* @return
*/
Request jsonObjectRequest(String requestBody, HttpRequest httpRequest, HttpListener<JSONObject> listener, Object tag);
/**
* JsonArray请求
*/
Request jsonArrayRequest(String requestBody, HttpRequest httpRequest, HttpListener<JSONArray> listener, Object tag);
/**
* Gson请求,可以映射Model
*/
<T> Request gsonRequest(Class<T> tClass, TypeToken<T> typeToken, HttpRequest httpRequest, HttpListener<T> listener, Object tag);
}
- 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
然后再写一个具体的实现类即可。
package com.yong.volleyok;
/**
* <b>Project:</b> com.yong.volleyok.http <br>
* <b>Create Date:</b> 2016/4/23 <br>
* <b>Author:</b> qingyong <br>
* <b>Description:</b> 请求的具体实现类 <br>
*/
public class HttpClient implements IHttpClient {
private static HttpClient INSTANCE;
private static final int[] sLock = new int[0];
private final RequestQueue mRequestQueue;
private final Context mContext;
private HttpClient(Context context) {
mContext = context;
mRequestQueue = Volley.newRequestQueue(context,
new OkHttp3Stack(new OkHttpClient()));
}
/**
* 这里使用Application的Context
*
* @param context
* @return
*/
public static HttpClient getInstance(Context context) {
if (null == INSTANCE) {
synchronized (sLock) {
if (null == INSTANCE) {
INSTANCE = new HttpClient(context);
}
}
}
return INSTANCE;
}
/**
* 添加请求
*
* @param request
*/
public void addRequest(Request request, Object tag) {
if (tag != null) {
request.setTag(tag);
}
mRequestQueue.add(request);
}
/**
* 取消请求
*
* @param tag
*/
public void cancelRequest(Object tag) {
mRequestQueue.cancelAll(tag);
}
public Request ByteRequest(HttpRequest httpRequest, HttpListener<byte[]> listener) {
return byteRequest(httpRequest, listener, null);
}
@Override
public Request byteRequest(HttpRequest httpRequest, HttpListener<byte[]> listener, Object tag) {
ByteRequest request = new ByteRequest(httpRequest, listener);
addRequest(request, tag);
return request;
}
public Request stringRequest(HttpRequest httpRequest, HttpListener<String> listener) {
return stringRequest(httpRequest, listener, null);
}
@Override
public Request stringRequest(HttpRequest httpRequest, HttpListener<String> listener, Object tag) {
StringRequest request = new StringRequest(httpRequest, listener);
addRequest(request, tag);
return request;
}
public Request gZipRequest(HttpRequest httpRequest, HttpListener<String> listener) {
return gZipRequest(httpRequest, listener, null);
}
@Override
public Request gZipRequest(HttpRequest httpRequest, HttpListener<String> listener, Object tag) {
GZipRequest request = new GZipRequest(httpRequest, listener);
addRequest(request, tag);
return request;
}
public Request jsonObjectRequest(HttpRequest httpRequest, HttpListener<JSONObject> listener) {
return jsonObjectRequest(null, httpRequest, listener);
}
public Request jsonObjectRequest(String requestBody, HttpRequest httpRequest, HttpListener<JSONObject> listener) {
return jsonObjectRequest(requestBody, httpRequest, listener, null);
}
@Override
public Request jsonObjectRequest(String requestBody, HttpRequest httpRequest, HttpListener<JSONObject> listener, Object tag) {
JsonObjectRequest request = new JsonObjectRequest(requestBody, httpRequest, listener);
addRequest(request, tag);
return request;
}
public Request jsonArrayRequest(HttpRequest httpRequest, HttpListener<JSONArray> listener) {
return jsonArrayRequest(httpRequest, listener, null);
}
public Request jsonArrayRequest(HttpRequest httpRequest, HttpListener<JSONArray> listener, Object tag) {
return jsonArrayRequest(null, httpRequest, listener, tag);
}
@Override
public Request jsonArrayRequest(String requestBody, HttpRequest httpRequest, HttpListener<JSONArray> listener, Object tag) {
JsonArrayRequest request = new JsonArrayRequest(requestBody, httpRequest, listener);
addRequest(request, tag);
return request;
}
public <T> Request gsonRequest(Class<T> tClass, HttpRequest httpRequest, HttpListener<T> listener) {
return gsonRequest(tClass, httpRequest, listener, null);
}
public <T> Request gsonRequest(Class<T> tClass, HttpRequest httpRequest, HttpListener<T> listener, Object tag) {
return gsonRequest(tClass, null, httpRequest, listener, tag);
}
@Override
public <T> Request gsonRequest(Class<T> tClass, TypeToken<T> typeToken,
HttpRequest httpRequest, HttpListener<T> listener, Object tag) {
GsonRequest<T> request = new GsonRequest<T>(tClass, typeToken, httpRequest, listener);
addRequest(request, tag);
return request;
}
}
- 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
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
六、使用
当然使用也非常简单,看HttpClient就知道有哪些方法。
mResult = (TextView) findViewById(R.id.result)
mHttpClient = HttpUtil.getHttpClient()
HttpRequest request = new HttpRequest.Builder("http://www.mocky.io/v2/571b3c270f00001a0faddfcc")
.setMethod(Request.Method.GET)
.build()
mHttpClient.stringRequest(request, new HttpListener<String>() {
@Override
public void onSuccess(String result) {
Log.e("TAG", result)
mResult.setText(result)
}
@Override
public void onError(VolleyError error) {
mResult.setText(error.getMessage())
}
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
库和Demo地址:
https://github.com/qingyongai/VolleyOkExtension