欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中volley封裝實(shí)踐記錄(二)

 更新時(shí)間:2019年02月02日 10:50:13   作者:一朵喇叭花嗚拉嗚拉  
這篇文章主要給大家介紹了關(guān)于Android中volley封裝的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

關(guān)于android的volley封裝之前寫(xiě)過(guò)一篇文章,見(jiàn)鏈接(http://www.dbjr.com.cn/article/155875.htm)。這篇文章主要是換種方式進(jìn)行封裝,具體步驟如下所示。

步驟如下

1.創(chuàng)建Request,并設(shè)置相應(yīng)的參數(shù):

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;
 }

}

所做的工作也很簡(jiǎn)單,去配置網(wǎng)絡(luò)訪問(wèn)RetryPolicy,比如超時(shí)時(shí)間,最大的重試次數(shù)。例外也會(huì)根據(jù)業(yè)務(wù)要求在請(qǐng)求的頭部加入token等標(biāo)識(shí)。

2.通過(guò)工廠模式創(chuàng)建請(qǐng)求隊(duì)列,volley內(nèi)部會(huì)有兩種構(gòu)造方式,同步請(qǐng)求或者異步請(qǐng)求,通過(guò)設(shè)置ResponseDelivery 可以實(shí)現(xiàn)。

public interface ResponseDelivery {
 /**
 * Parses a response from the network or cache and delivers it.
 */
 public void postResponse(Request<?> 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);
}

這個(gè)工廠的代碼如下:

/**
 * 網(wǎng)絡(luò)請(qǐng)求隊(duì)列工廠類
 */
public class RequestQueueFactory {

 private static RequestQueue sRequestQueue;
 private static RequestQueue sAsynRequestQueue;

 private static int ASYN_QUEUE_THREAD_POOL_SIZE = 3;

 private RequestQueueFactory() {

 }

 /**
 * 獲取默認(rèn)RequestQueue,回調(diào)是同步到主線程的
 *
 * @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,回調(diào)是在異步線程的
 *
 * @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,如果不進(jìn)行設(shè)置,內(nèi)部默認(rèn)的會(huì)設(shè)置一個(gè)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高上一個(gè)遍歷元素的速度
//  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.封裝基類?;愂褂胊bstract會(huì)更靈活,子類可以選擇性的重寫(xiě)方法。

/**
 * 網(wǎng)絡(luò)處理基類
 */
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);
 }

 /**
 * 推薦用頁(yè)面ClassName+時(shí)間戳
 *
 * @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 是否帶上頁(yè)面的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.邏輯封裝。

這里選用的是一個(gè)新聞的接口,這種接口可以在聚合數(shù)據(jù)上申請(qǐng),有的收費(fèi),有的免費(fèi)。

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.開(kāi)始使用。

 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();
 }

最后放一張圖:

圖片發(fā)自簡(jiǎn)書(shū)App

分享結(jié)束,代碼在[github] (https://github.com/daydaydate/sample (本地下載))  。感謝您的閱讀。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Android 圖片保存到相冊(cè)不顯示的解決方案(兼容Android 10及更高版本)

    Android 圖片保存到相冊(cè)不顯示的解決方案(兼容Android 10及更高版本)

    這篇文章主要介紹了Android 圖片保存到系統(tǒng)相冊(cè)不顯示的解決方案,幫助大家更好的理解和學(xué)習(xí)使用Android開(kāi)發(fā),感興趣的朋友可以了解下
    2021-04-04
  • android獲取圖片尺寸的兩種方式及bitmap的縮放操作

    android獲取圖片尺寸的兩種方式及bitmap的縮放操作

    這篇文章主要介紹了android獲取圖片尺寸的兩種方式及bitmap的縮放操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Android Koin2基本使用的那件事兒

    Android Koin2基本使用的那件事兒

    這篇文章主要給大家介紹了關(guān)于Android Koin2基本使用的那件事兒,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Android中使用SDcard讀取文件

    Android中使用SDcard讀取文件

    這篇文章主要介紹了Android中使用SDcard讀取文件的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Android編程設(shè)計(jì)模式之策略模式詳解

    Android編程設(shè)計(jì)模式之策略模式詳解

    這篇文章主要介紹了Android編程設(shè)計(jì)模式之策略模式,結(jié)合實(shí)例形式詳細(xì)分析了Android策略模式的概念、原理、實(shí)現(xiàn)方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-12-12
  • Android權(quán)限機(jī)制深入分析講解

    Android權(quán)限機(jī)制深入分析講解

    Android的權(quán)限管理遵循的是“最小特權(quán)原則”,即所有的Android應(yīng)用程序都被賦予了最小權(quán)限。一個(gè)Android應(yīng)用程序如果沒(méi)有聲明任何權(quán)限,就沒(méi)有任何特權(quán)
    2022-12-12
  • Flutter自定義底部導(dǎo)航欄的方法

    Flutter自定義底部導(dǎo)航欄的方法

    這篇文章主要為大家詳細(xì)介紹了Flutter自定義底部導(dǎo)航欄的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • VideoView實(shí)現(xiàn)視頻無(wú)縫連續(xù)播放

    VideoView實(shí)現(xiàn)視頻無(wú)縫連續(xù)播放

    這篇文章主要為大家詳細(xì)介紹了VideoView實(shí)現(xiàn)視頻無(wú)縫連續(xù)播放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 使用Jetpack Compose實(shí)現(xiàn)翻轉(zhuǎn)卡片效果流程詳解

    使用Jetpack Compose實(shí)現(xiàn)翻轉(zhuǎn)卡片效果流程詳解

    Jetpack Compose 是一款基于 Kotlin 的聲明式 UI 工具包,可以方便地創(chuàng)建漂亮的用戶界面。使用 Compose 的動(dòng)畫(huà) API 和可繪制 API,可以輕松實(shí)現(xiàn)翻轉(zhuǎn)卡片效果。通過(guò)設(shè)置旋轉(zhuǎn)角度和透明度等屬性,可以使卡片沿著 Y 軸翻轉(zhuǎn),并實(shí)現(xiàn)翻頁(yè)效果
    2023-05-05
  • Android?ViewPager你可能不知道的刷新操作分享

    Android?ViewPager你可能不知道的刷新操作分享

    這篇文章主要為大家詳細(xì)介紹了Android中ViewPager你可能不知道的刷新操作,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下
    2023-05-05

最新評(píng)論