Android中volley封装实践记录(二)

发布时间:2019-08-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Android中volley封装实践记录(二)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

关于android的volley封装之前写过一篇文章,见链接(https://www.jb51.net/article/155875.htm)。这篇文章主要是换种方式进行封装,具体步骤如下所示。

步骤如下

1.创建Request,并设置相应的参数:

 public class CommonJsonObjectRequest extends JsonObjectRequest {  PRivate String TAG = this.getClass().getSimpleName();  /*  * code=1:处理成功;  */  public static final int CODE_SUCCESS = 100;  private Context mContext;  private JSONObject mJsonRequest;   public CommonJsonObjectRequest(Context context, int method, String url,      JSONObject jsonRequest, Response.Listener<JSONObject> listener,      Response.ErrorListener errorListener) {  suPEr(method, url, jsonRequest, listener, errorListener);  inIT(context, jsonRequest);  }   /**  * @param context  * @param url  * @param jsonRequest  * @param listener  * @param errorListener  */  public CommonJsonObjectRequest(Context context, String url, JSONObject jsonRequest,      Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {  super(url, jsonRequest, listener, errorListener);  if (jsonRequest != null) {   LOG.d(TAG, jsonRequest.toString());  }  init(context, jsonRequest);  }   /**  * @param context  * @param jsonRequest  */  private void init(Context context, JSONObject jsonRequest) {  this.mContext = context.getApplicationContext();  this.mJsonRequest = jsonRequest;  setRetrypolicy(new DefaultRetryPolicy(10 * 1000, 0, 0));  }   @override  public Map<String, String> getHeaders() throws AuthFailureError {  Map<String, String> headersMap = new HashMap<>();  //do your business requirement  return headersMap;  }  }

所做的工作也很简单,去配置网络访问RetryPolicy,比如超时时间,最大的重试次数。例外也会根据业务要求在请求的头部加入token等标识。

2.通过工厂模式创建请求队列,volley内部会有两种构造方式,同步请求或者异步请求,通过设置ResponseDelivery 可以实现。

 public interface ResponseDelivery {  /**  * Parses a response From the network or cache and delivers it.  */  public void postResponse(Request<&#63;> request, Response<?> response);   /**  * Parses a response from the network or cache and delivers it. The provided  * Runnable will be executed after delivery.  */  public void postResponse(Request<?> request, Response<?> response, Runnable runnable);   /**  * Posts an error for the given request.  */  public void postError(Request<?> request, VolleyError error); }

这个工厂的代码如下:

 /**  * 网络请求队列工厂类  */ public class RequestQueueFactory {   private static RequestQueue sRequestQueue;  private static RequestQueue sAsynRequestQueue;   private static int ASYN_QUEUE_THREAD_POOL_SIZE = 3;   private RequestQueueFactory() {   }   /**  * 获取默认RequestQueue,回调是同步到主线程的  *  * @param context  * @return  */  public synchronized static RequestQueue getRequestQueue(Context context) {  if (sRequestQueue == null) {   OkHttpClient okHttpClient = new OkHttpClient.Builder().build();   OkHttpStack stack = new OkHttpStack(okHttpClient);   sRequestQueue = Volley.newRequestQueue(context, stack);  }  return sRequestQueue;  }   /**  * 获取异步RequestQueue,回调是在异步线程的  *  * @param context  * @return  */  public synchronized static RequestQueue getAsynRequeQueueRespond(   final Context context) {  if (sAsynRequestQueue == null) {   sAsynRequestQueue = getAsynRequeQueueRespond(context,    ASYN_QUEUE_THREAD_POOL_SIZE);  }  return sAsynRequestQueue;  }   private static RequestQueue getAsynRequeQueueRespond(final Context context,         int threadPoolSize) {  File cacheDir = new File(context.getCacheDir(), "volley_asyn");  OkHttpClient okHttpClient = new OkHttpClient.Builder().build();  OkHttpStack stack = new OkHttpStack(okHttpClient);  Network network = new BasicNetwork(stack);  RequestQueue queue = new RequestQueue(new diskBasedCache(cacheDir),   network, threadPoolSize, new ExecutorDelivery(   AsyncTask.SERIAL_EXECUTOR));  queue.start();  return queue;  }  }

在代码中有这样两行代码:

  if (sRequestQueue == null) {   OkHttpClient okHttpClient = new OkHttpClient.Builder().build();   OkHttpStack stack = new OkHttpStack(okHttpClient);   sRequestQueue = Volley.newRequestQueue(context, stack);  }

这里是使用了okhttpstack,如果不进行设置,内部默认的会设置一个stack;

  if (stack == null) {   if (Build.VERSION.SDK_INT >= 9) {   stack = new HurlStack();   } else {   // Prior to gingerbread, HttpUrlConnection was unreliable.   // See: http://andROId-developers.blogspot.COM/2011/09/androids-http-clients.htML   stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));   }  }

okhttpstack类如下:

 /**  * 使用OKHttp作为底层的HttpStack  */ public class OkHttpStack implements HttpStack {  private final OkHttpClient client;   public OkHttpStack(OkHttpClient client) {  this.client = client;  }   private static HttpEntity entityFromOkHttpResponse(Response response) throws IOException {  BasicHttpEntity entity = new BasicHttpEntity();  ResponseBody body = response.body();   entity.setContent(body.bytestream());  entity.setContentLength(body.contentLength());  entity.setContentEncoding(response.header("Content-Encoding"));   if (body.contentType() != null) {   entity.setContentType(body.contentType().type());  }  return entity;  }   @SupPressWarnings("deprecation")  private static void setConnectionParametersForRequest   (okhttP3.Request.Builder builder, Request<?> request)   throws IOException, AuthFailureError {  switch (request.getMethod()) {   case Request.Method.DEPRECATED_GET_OR_POST:   byte[] postBody = request.getPostBody();   if (postBody != null) {    builder.post(RequestBody.create     (MediaType.parse(request.getPostBodyContentType()), postBody));   }   break;    case Request.Method.GET:   builder.get();   break;    case Request.Method.DELETE:   builder.delete();   break;    case Request.Method.POST:   builder.post(createRequestBody(request));   break;    case Request.Method.PUT:   builder.put(createRequestBody(request));   break;    case Request.Method.HEAD:   builder.head();   break;    case Request.Method.OPTIONS:   builder.method("OPTIONS", null);   break;    case Request.Method.TRACE:   builder.method("TRACE", null);   break;    case Request.Method.PATCH:   builder.patch(createRequestBody(request));   break;    default:   throw new IllegalStateException("Unknown method type.");  }  }   private static RequestBody createRequestBody(Request request) throws AuthFailureError {  final byte[] body = request.getBody();  if (body == null) return null;   return RequestBody.create(MediaType.parse(request.getBodyContentType()), body);  }   private static ProtocolVersion parseProtocol(final Protocol protocol) {  switch (protocol) {   case HTTP_1_0:   return new ProtocolVersion("HTTP", 1, 0);   case HTTP_1_1:   return new ProtocolVersion("HTTP", 1, 1);   case SPDY_3:   return new ProtocolVersion("SPDY", 3, 1);   case HTTP_2:   return new ProtocolVersion("HTTP", 2, 0);  }   throw new IllegalAccessError("Unkwown protocol");  }   @Override  public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)   throws IOException, AuthFailureError {  int timeoutMs = request.getTimeoutMs();  OkHttpClient client = this.client.newBuilder()   .readTimeout(timeoutMs, TimeUnit.MILLISECONDS)   .connectTimeout(timeoutMs, TimeUnit.MILLISECONDS)   .writeTimeout(timeoutMs, TimeUnit.MILLISECONDS)   .build();   okhttp3.Request.Builder okHttpRequestBuilder = new okhttp3.Request.Builder();  Map<String, String> headers = request.getHeaders();   for (Map.Entry<String,String> entry : headers.entrySet()) {   okHttpRequestBuilder.addHeader(entry.getKey(), entry.getValue());  }   for (Map.Entry<String,String> entry : additionalHeaders.entrySet()) {   okHttpRequestBuilder.addHeader(entry.getKey(), entry.getValue());  }  // for (final String name : headers.keySet()) { //entrySet的遍历效率比keySet高上一个遍历元素的速度 //  okHttpRequestBuilder.addHeader(name, headers.get(name)); // }  // for (final String name : additionalHeaders.keySet()) { //  okHttpRequestBuilder.addHeader(name, additionalHeaders.get(name)); // }   setConnectionParametersForRequest(okHttpRequestBuilder, request);   okhttp3.Request okhttp3Request = okHttpRequestBuilder.url(request.getUrl()).build();  Response okHttpResponse = client.newCall(okhttp3Request).execute();   StatusLine responseStatus = new BasicStatusLine   (    parseProtocol(okHttpResponse.protocol()),    okHttpResponse.code(),    okHttpResponse.message()   );  BasicHttpResponse response = new BasicHttpResponse(responseStatus);  response.setEntity(entityFromOkHttpResponse(okHttpResponse));   Headers responseHeaders = okHttpResponse.headers();  for (int i = 0, len = responseHeaders.size(); i < len; i++) {   final String name = responseHeaders.name(i), value = responseHeaders.value(i);   if (name != null) {   response.addHeader(new BasicHeader(name, value));   }  }  return response;  } }

其中核心代码在PerformRequest方法中。

3.封装基类。基类使用abstract会更灵活,子类可以选择性的重写方法。

 /**  * 网络处理基类  */ public abstract class BaseNetModel {   protected RequestQueue requestQueue;  protected Context context;  protected Object mtag;   protected BaseNetModel(Context context) {  this.context = context.getApplicationContext();  requestQueue = RequestQueueFactory.getAsynRequeQueueRespond(this.context);  }   protected BaseNetModel(Context context, boolean isAsyn) {  this.context = context.getApplicationContext();  requestQueue = isAsyn ? RequestQueueFactory.getAsynRequeQueueRespond(this.context)   : RequestQueueFactory.getRequestQueue(context);  }   /**  * 推荐用页面classname+时间戳  *  * @param tag  */  public void setTag(Object tag) {  this.mTag = tag;  }   public void destroy() {  if (mTag != null) {   cancelTaskByTag(mTag);  }  requestQueue = null;  context = null;  }   public void cancelTaskByTag(Object tag) {  if (requestQueue != null) {   requestQueue.cancelAll(tag);  }  }    public void addRequest(String path, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {  addRequest(path, true, jsonRequest, listener, errorListener);  }   /**  * @param path  不带域名的接口路径  * @param withTag 是否带上页面的tag  * @param jsonRequest  * @param listener  * @param errorListener  */  public void addRequest(String path, boolean withTag, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {  addRequestUrl(path, withTag, jsonRequest, listener, errorListener);  }   /**  * @param url  完整接口地址  * @param withTag  * @param jsonRequest  * @param listener  * @param errorListener  */  public void addRequestUrl(String url, boolean withTag, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {  if (jsonRequest == null) {   jsonRequest = new JSONObject();  }  CommonJsonObjectRequest request = new CommonJsonObjectRequest(context, url, jsonRequest, listener, errorListener);  if (withTag && mTag != null) {   request.setTag(mTag);  }  requestQueue.add(request);  }  }

4.逻辑封装。

这里选用的是一个新闻的接口,这种接口可以在聚合数据上申请,有的收费,有的免费。

 public class NewsModel extends BaseNetModel {  public NewsModel(Context context) {  super(context);  }   public NewsModel(Context context, boolean isAsyn) {  super(context, isAsyn);  }   public void getInfo(Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) throws Exception {  JSONObject jsonObject = new JSONObject();  addRequest(inetConstant.NEWS, jsonObject, listener, errorListener);  } }

接口的地址为:(http://v.juhe.cn/toutiao/index?type=&key=b2f8e4aeaCFa310cabfadd5189bbe4d5)

5.开始使用。

  NewsModel newsModel = new NewsModel(getActivity());  try {   newsModel.getInfo(new Response.Listener<JSONObject>() {   @Override   public void onResponse(final JSONObject response) {    ThreadUtils.runInUIThread(new Runnable() {    @Override    public void run() {     News news = new Gson().fromJson(response.toString(), News.class);     mAdapter.setData(news.getResult().getData());    }    });   }   }, new Response.ErrorListener() {   @Override   public void onErrorResponse(VolleyError error) {   }   });  } catch (Exception e) {   e.printStackTrace();  }

最后放一张图:

Android中volley封装实践记录(二)

图片发自简书App

分享结束,代码在[github] (https://github.com/daydaydate/sample (本地下载))  。感谢您的阅读。

总结

android教程
脚本网站
android studio

脚本宝典总结

以上是脚本宝典为你收集整理的Android中volley封装实践记录(二)全部内容,希望文章能够帮你解决Android中volley封装实践记录(二)所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。