Back to project page NetworkFacade.
The source code is released under:
Apache License
If you think the Android project NetworkFacade listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.saguinav.networkfacade.sample; // ww w .j a v a 2 s .co m import android.content.Context; import android.text.TextUtils; import com.android.volley.AuthFailureError; import com.android.volley.Cache; import com.android.volley.DefaultRetryPolicy; import com.android.volley.Network; import com.android.volley.NetworkError; import com.android.volley.NetworkResponse; import com.android.volley.NoConnectionError; import com.android.volley.ParseError; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.ServerError; import com.android.volley.TimeoutError; import com.android.volley.VolleyError; import com.android.volley.VolleyLog; import com.android.volley.toolbox.AuthenticationChallengesProofHurlStack; import com.android.volley.toolbox.BasicNetwork; import com.android.volley.toolbox.DiskBasedCache; import com.android.volley.toolbox.HttpHeaderParser; import com.saguinav.networkfacade.HttpClient; import com.saguinav.networkfacade.HttpError; import com.saguinav.networkfacade.HttpRequest; import org.apache.http.HttpStatus; import java.io.File; import java.io.UnsupportedEncodingException; import java.util.Map; public class VolleyHttpClient implements HttpClient { /** Default on-disk cache directory. */ private static final String DEFAULT_CACHE_DIR = "volley"; /** Default maximum disk usage in bytes. */ private static final int DEFAULT_DISK_USAGE_BYTES = 5 * 1024 * 1024; // 5 MiB private final RequestQueue mRequestQueue; public VolleyHttpClient(Context context) { final File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR); Network network = new BasicNetwork(new AuthenticationChallengesProofHurlStack()); mRequestQueue = new RequestQueue(new DiskBasedCache(cacheDir, DEFAULT_DISK_USAGE_BYTES), network); mRequestQueue.start(); } @Override public void performRequest(HttpRequest request, ResponseListener responseListener) { final Request<?> volleyRequest = new VolleyHttpRequestWrapper(request, responseListener); volleyRequest.setShouldCache(request.getCachePolicy() != 0); if (request.getRetryPolicy() != null) { volleyRequest.setRetryPolicy(new DefaultRetryPolicy(request.getRetryPolicy().getTimeOut(), request.getRetryPolicy().getMaxNumRetries(), request.getRetryPolicy().getBackoffMultiplier())); } mRequestQueue.add(volleyRequest); } private static String networkData2String(byte[] data, Map<String, String> headers) throws UnsupportedEncodingException { return new String(data, HttpHeaderParser.parseCharset(headers)); } private static class VolleyHttpRequestWrapper extends Request<String> { private final HttpRequest mRequest; private final ResponseListener mResponseListener; public VolleyHttpRequestWrapper(HttpRequest request, ResponseListener responseListener) { super(getRequestMethod(request.getMethod()), request.getUrl(), new VolleyErrorListener(responseListener)); mRequest = request; mResponseListener = responseListener; } @Override protected Response<String> parseNetworkResponse(NetworkResponse response) { try { Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); if (shouldCache()) { if (entry == null || entry.ttl == 0 || TextUtils.isEmpty(response.headers.get("Cache-Control"))) { entry = parseIgnoringCacheHeaders(response, mRequest.getCachePolicy()); } } return Response.success(networkData2String(response.data, response.headers), entry); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(String response) { mResponseListener.onSuccess(response); } @Override public String getBodyContentType() { return mRequest.getBody() != null && mRequest.getBody().getType() != null ? mRequest.getBody().getType() : super.getBodyContentType(); } @Override public byte[] getBody() { if (mRequest.getBody() == null) return null; final String body = mRequest.getBody().getContent(); final String bodyContentEncoding = mRequest.getBody().getEncoding(); try { return body.getBytes(bodyContentEncoding); } catch (UnsupportedEncodingException uee) { VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", body, bodyContentEncoding); return null; } } private static int getRequestMethod(HttpRequest.Method method) { switch (method) { case GET: return Request.Method.GET; case POST: return Request.Method.POST; case PUT: return Request.Method.PUT; case DELETE: return Request.Method.DELETE; default: VolleyLog.wtf("Unmappable HttpRequest.Method"); return -1; } } /** * Extracts a {@link Cache.Entry} from a {@link NetworkResponse}. * Cache-control headers are ignored. SoftTtl == 3 mins, ttl == 24 hours. * @param response The network response to parse headers from * @return a cache entry for the given response, or null if the response is not cacheable. */ private static Cache.Entry parseIgnoringCacheHeaders(NetworkResponse response, long cachePolicy) { long now = System.currentTimeMillis(); Map<String, String> headers = response.headers; long serverDate = 0; String serverEtag; String headerValue; headerValue = headers.get("Date"); if (headerValue != null) { serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue); } serverEtag = headers.get("ETag"); final long softExpire = now + cachePolicy; Cache.Entry entry = new Cache.Entry(); entry.data = response.data; entry.etag = serverEtag; entry.softTtl = softExpire; entry.ttl = entry.softTtl; entry.serverDate = serverDate; entry.responseHeaders = headers; return entry; } private static class VolleyErrorListener implements Response.ErrorListener { private final ResponseListener mResponseListener; public VolleyErrorListener(ResponseListener responseListener) { mResponseListener = responseListener; } @Override public void onErrorResponse(VolleyError error) { final HttpError.Code errorCode; String message = null; if (error instanceof NoConnectionError) { errorCode = HttpError.Code.NO_CONNECTION; } else if (error instanceof NetworkError) { errorCode = HttpError.Code.NETWORK; } else if (error instanceof AuthFailureError || error instanceof ServerError) { // Volley throws an AuthFailureError when the server returns a 401. // It will be treated as a Server error. if (error.networkResponse != null) { if (error.networkResponse.statusCode >= HttpStatus.SC_BAD_REQUEST && error.networkResponse.statusCode < HttpStatus.SC_INTERNAL_SERVER_ERROR) { errorCode = HttpError.Code.CLIENT; try { message = networkData2String(error.networkResponse.data, error.networkResponse.headers); } catch (UnsupportedEncodingException e) { message = e.getMessage(); } } else { errorCode = HttpError.Code.SERVER; } } else { errorCode = HttpError.Code.SERVER; } } else if (error instanceof TimeoutError) { errorCode = HttpError.Code.TIME_OUT; } else if (error instanceof ParseError) { errorCode = HttpError.Code.PARSE; } else { errorCode = HttpError.Code.UNKNOWN; } if (message == null) { message = error.getMessage(); } mResponseListener.onFailure(new HttpError(errorCode, message, error.getCause())); } } } }