转载请注明本文出自Cym的博客(),谢谢支持!
之前讲了,大家应该了解了volley的使用,接下来我们要看看如何把volley使用到实战项目里面,我们先考虑下一些问题:
从上一篇来看 mQueue 只需要一个对象即可,new RequestQueue对象对资源一种浪费,我们应该在application,以及可以把取消请求的方法也在application进行统一管理,看以下代码:
- package com.chronocloud.lib.base;
-
- import android.app.Application;
- import android.text.TextUtils;
-
- import com.android.volley.Request;
- import com.android.volley.RequestQueue;
- import com.android.volley.VolleyLog;
- import com.android.volley.toolbox.Volley;
-
- public class ApplicationController extends Application {
-
-
-
-
- public static final String TAG = "VolleyPatterns";
-
-
-
-
- private RequestQueue mRequestQueue;
-
-
-
-
-
- private static ApplicationController sInstance;
-
- @Override
- public void onCreate() {
- super.onCreate();
-
-
- sInstance = this;
- }
-
-
-
-
- public static synchronized ApplicationController getInstance() {
- return sInstance;
- }
-
-
-
-
- public RequestQueue getRequestQueue() {
-
-
- if (mRequestQueue == null) {
-
-
- synchronized (ApplicationController.class) {
- if (mRequestQueue == null) {
- mRequestQueue = Volley
- .newRequestQueue(getApplicationContext());
- }
- }
- }
- return mRequestQueue;
- }
-
-
-
-
-
-
-
-
- public <T> void addToRequestQueue(Request<T> req, String tag) {
-
- req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
-
- VolleyLog.d("Adding request to queue: %s", req.getUrl());
-
- getRequestQueue().add(req);
- }
-
-
-
-
-
-
-
- public <T> void addToRequestQueue(Request<T> req) {
-
- req.setTag(TAG);
-
- getRequestQueue().add(req);
- }
-
-
-
-
-
-
-
- public void cancelPendingRequests(Object tag) {
- if (mRequestQueue != null) {
- mRequestQueue.cancelAll(tag);
- }
- }
- }
接下来 就是Volley虽然给我们提供了很多不同的Request(JsonObjectRequest,JsonArrayRequest,StringRequest,ImageRequest),但是还是满足不了我们实战中的需求,我们实战开发中经常用到的是xml格式,Gson解析。
接下来我们来看看,如何自定义Request
XmlRequest:
- public class XMLRequest extends Request<XmlPullParser> {
-
- private final Listener<XmlPullParser> mListener;
-
- public XMLRequest(int method, String url, Listener<XmlPullParser> listener,
- ErrorListener errorListener) {
- super(method, url, errorListener);
- mListener = listener;
- }
-
- public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {
- this(Method.GET, url, listener, errorListener);
- }
-
- @Override
- protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
- try {
- String xmlString = new String(response.data,
- HttpHeaderParser.parseCharset(response.headers));
- XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
- XmlPullParser xmlPullParser = factory.newPullParser();
- xmlPullParser.setInput(new StringReader(xmlString));
- return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
- } catch (UnsupportedEncodingException e) {
- return Response.error(new ParseError(e));
- } catch (XmlPullParserException e) {
- return Response.error(new ParseError(e));
- }
- }
-
- @Override
- protected void deliverResponse(XmlPullParser response) {
- mListener.onResponse(response);
- }
-
- }
GsonRequest(注意需要自行导入gson.jar):
- public class GsonRequest<T> extends Request<T> {
-
- private final Listener<T> mListener;
-
- private Gson mGson;
-
- private Class<T> mClass;
-
- public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener,
- ErrorListener errorListener) {
- super(method, url, errorListener);
- mGson = new Gson();
- mClass = clazz;
- mListener = listener;
- }
-
- public GsonRequest(String url, Class<T> clazz, Listener<T> listener,
- ErrorListener errorListener) {
- this(Method.GET, url, clazz, listener, errorListener);
- }
-
- @Override
- protected Response<T> parseNetworkResponse(NetworkResponse response) {
- try {
- String jsonString = new String(response.data,
- HttpHeaderParser.parseCharset(response.headers));
- return Response.success(mGson.fromJson(jsonString, mClass),
- HttpHeaderParser.parseCacheHeaders(response));
- } catch (UnsupportedEncodingException e) {
- return Response.error(new ParseError(e));
- }
- }
-
- @Override
- protected void deliverResponse(T response) {
- mListener.onResponse(response);
- }
-
- }
接下只差最后一步了就是封装它的错误处理,使用过volley的都知道,volley的监听错误提示都是NoConnectionError。。。等等,这类的错误提示,显然这不是我们想给用户呈现的错误提示,因为就算提示了用户也不明白什么意思,所以我们还要封装一下,能让用户看的更清楚的理解这些错误提示。我们讲过每个请求都需要设置一个失败的监听:
-
- private class StrErrListener implements ErrorListener {
-
- @Override
- public void onErrorResponse(VolleyError arg0) {
- Toast.makeText(mContext,
- VolleyErrorHelper.getMessage(arg0, mContext),
- Toast.LENGTH_LONG).show();
- }
-
- }
以上代码有个VolleyError对象,我们可以从这个对象上下手:
- package com.example.volley;
-
- import java.util.HashMap;
- import java.util.Map;
-
- import android.content.Context;
-
- import com.android.volley.AuthFailureError;
- import com.android.volley.NetworkError;
- import com.android.volley.NetworkResponse;
- import com.android.volley.NoConnectionError;
- import com.android.volley.ServerError;
- import com.android.volley.TimeoutError;
- import com.android.volley.VolleyError;
- import com.google.gson.Gson;
- import com.google.gson.reflect.TypeToken;
-
-
-
-
-
-
-
-
-
- public class VolleyErrorHelper {
-
-
-
-
-
-
-
-
-
- public static String getMessage(Object error, Context context) {
- if (error instanceof TimeoutError) {
- return context.getResources().getString(
- R.string.generic_server_down);
- } else if (isServerProblem(error)) {
- return handleServerError(error, context);
- } else if (isNetworkProblem(error)) {
- return context.getResources().getString(R.string.no_internet);
- }
- return context.getResources().getString(R.string.generic_error);
- }
-
-
-
-
-
-
-
- private static boolean isNetworkProblem(Object error) {
- return (error instanceof NetworkError)
- || (error instanceof NoConnectionError);
- }
-
-
-
-
-
-
-
- private static boolean isServerProblem(Object error) {
- return (error instanceof ServerError)
- || (error instanceof AuthFailureError);
- }
-
-
-
-
-
-
-
-
-
- private static String handleServerError(Object err, Context context) {
- VolleyError error = (VolleyError) err;
-
- NetworkResponse response = error.networkResponse;
-
- if (response != null) {
- switch (response.statusCode) {
- case 404:
- case 422:
- case 401:
- try {
-
-
-
- HashMap<String, String> result = new Gson().fromJson(
- new String(response.data),
- new TypeToken<Map<String, String>>() {
- }.getType());
-
- if (result != null && result.containsKey("error")) {
- return result.get("error");
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return error.getMessage();
-
- default:
- return context.getResources().getString(
- R.string.generic_server_down);
- }
- }
- return context.getResources().getString(R.string.generic_error);
- }
- }
以上代码中引用的xml是:
- <string name="no_internet">无网络连接~!</string>
- <string name="generic_server_down">连接服务器失败~!</string>
- <string name="generic_error">网络异常,请稍后再试~!</string>
接下来,数据请求这一块已经说完了,我们来说下图片这一块,我个人喜欢使用universal-image-loader而不是volley自己提供的(个人认为使用起来
universal-image-loader更便捷一些)。好啦讲完了,大家可以去实战开发了~!不懂或者遇到问题的可以留言讨论~!