网络框架-Volley
Volley概述:
Volley是Google 2013年I/O大会推出的针对Android的HTTP网络请求框架,让网络请求更简单,更快。
特点:
- 自动调度网络请求
- 支持并发网络连接
- 支持标准的HTTP缓存协议(由服务器来决定是否缓存数据)
- 支持请求优先级设置
- 支持取消单个或多个请求
- 易于定制,扩展性强。比如Retry&Backoff机制
- 强大的网络请求能力让你轻松的发送异步请求来填充UI数据
- 提供调试和跟踪工具
优点:
擅长将RPC(远程过程调用协议,C/S模式)类型的操作,用来展示服务器数据。比如以某种数据格式获取一页搜索结果。支持任意的数据传输格式,比如图片,字符串,json,你也可以定义自己的数据格式。其实就是自定义Request。Volley让你不再写这些重复的模板代码(网络请求逻辑,不再重复造轮子),这样你就可以专注于你应用本身的业务逻辑.
缺点:
由于Volley都是在内存中解析和处理数据,所以不适合大数据量的下载操作。如果需要下载大文件,可以考虑使用系统的DownloadManager
注意事项:
- 如果自己编译Volley的话,compileSdkVersion需要<=22,直接使用Volley框架
- 如果大于等于22,需要引入:useLibrary “org.apache.http.legacy”,集成httpClinet的Api(这是因为在Android6.0中Google移除了httpClient相关的API)
- Volley仅适合用于通信频繁数据量小的网络操作
- 大数据量的网络操作并不适合Volley
基本使用
发送get请求
String url = "http://www.oschina.net/action/api/blog_list?pageIndex=0&pageSize=20&type=latest";
RequestQueue requestQueue = Volley.newRequestQueue(this);
Request extends Object> request = new StringRequest(url, new Response.Listener() {
@Override
public void onResponse(String response) {
Toast.makeText(GetActivity.this, "结果 = " + response, Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(GetActivity.this, "错误 = " + error, Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(request);
发送post请求
String url = "http://www.oschina.net/action/api/login_validate";
final Map params = new HashMap<>();
params.put("keep_login", "1");
params.put("username", "xxx.com");
params.put("pwd", "xxx");
RequestQueue requestQueue = Volley.newRequestQueue(this);
Request extends Object> request = new StringRequest(Request.Method.POST, url, new Response.Listener() {
@Override
public void onResponse(String response) {
Toast.makeText(PostActivity.this, "登录成功 = " + response, Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PostActivity.this, "登录失败 = ", Toast.LENGTH_SHORT).show();
}
}) {
@Override
protected Map getParams() throws AuthFailureError {
return params;
}
};
requestQueue.add(request);
自定义请求对象(Request)
private class MyRequest extends Request<String>{
private Response.Listener<String>mListener;
private Map<String, String>params;
private Map<String, String>headers;
public MyRequest(int method, String url, Map<String, String> params, Map<String, String> headers, Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
this.params = params;
this.headers = headers;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
if(params == null){
params = Collections.EMPTY_MAP;
}
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
if(headers == null){
headers = Collections.EMPTY_MAP;
}
return headers;
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
}
自定义请求列队
DiskBasedCache diskBaseCache = new DiskBasedCache(getCacheDir(), 10 * 1024 * 1024);
BasicNetwork newtwork = new BasicNetwork(new HurlStack());
RequestQueue requestQueue = new RequestQueue(
diskBaseCache,
newtwork
);
String url = "http://www.oschina.net/action/api/blog_list?pageIndex=0&pageSize=20&type=latest";
Request extends Object> request = new StringRequest(url, new Response.Listener() {
@Override
public void onResponse(String response) {
Toast.makeText(RequestQueueActivity.this, "结果 = " + response, Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(RequestQueueActivity.this, "错误 = " + error, Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(request);
requestQueue.start();
上传文件
String url = "http://www.oschina.net/action/apiv2/resource_image";
RequestQueue requestQueue = Volley.newRequestQueue(this);
Map params = new HashMap<>();
params.put("resource", new File(Environment.getExternalStorageDirectory().getPath() + "/bear.png"));
MultipartRequest multipartRequest = new MultipartRequest(
url,
null,
params,
new Response.Listener(){
@Override
public void onResponse(String response) {
Toast.makeText(PostActivity.this, "登录成功 = " + response, Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PostActivity.this, "登录失败 = ", Toast.LENGTH_SHORT).show();
}
}
);
requestQueue.add(multipartRequest);
public class MultipartRequest extends Request {
private MultipartEntity entity;
private final Response.ListenermListener;
private ListpartList = new ArrayList();
private MapmHeaders;
public MultipartRequest(String url,
Response.ErrorListener errorListener,//
Response.Listener listener,//
Map params,//
Map headers
) {
super(Method.POST, url, errorListener);
mHeaders = headers;
mListener = listener;
if (params != null && params.size() >0) {
for (Map.Entry entry : params.entrySet()) {
String key = entry.getKey();
Object o = entry.getValue();
if (o instanceof File) {
try {
partList.add(new FilePart(key, (File) o));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
partList.add(new StringPart(key, (String) o));
}
}
}
buildMultipartEntity();
}
private void buildMultipartEntity() {
try {
entity = new MultipartEntity(partList.toArray(new Part[partList.size()]));
} catch (Exception e) {
VolleyLog.e("UnsupportedEncodingException");
}
}
@Override
public String getBodyContentType() {
return entity.getContentType().getValue();
}
@Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
entity.writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
@Override
protected Response parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
ALog.d(parsed);
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed,
HttpHeaderParser.parseCacheHeaders(response));
}
@Override
public Map getHeaders() throws AuthFailureError {
if (mHeaders == null || mHeaders.equals(Collections.emptyMap())) {
mHeaders = new HashMap();
}
return mHeaders;
}
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
自我感觉好繁琐...