麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統 > Android > 正文

Android中volley封裝實踐記錄

2019-10-21 21:25:48
字體:
來源:轉載
供稿:網友

前言

在項目中一般使用使用volley方式如下,用起來給人一種很亂的感覺,于是一種盤它的想法油然而生。

public void get() {String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=......";StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {   @Override   public void onResponse(String s) {    Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show();   }  }, new Response.ErrorListener() {   @Override   public void onErrorResponse(VolleyError volleyError) {    Toast.makeText(MainActivity.this,volleyError.toString(),Toast.LENGTH_SHORT).show();   }  });  request.setTag("abcGet");  MyApplication.getHttpQueues().add(request); }

首先看一下我封裝后的使用例子:

 private void initData() {  NewsApi.getInfo(new NetCallback<News>() {   @Override   public void OnSuccess(final News result) {    mAdapter.setData(result.getResult().getData());   }   @Override   public void OnError(RestfulError error) {   }  }); }

有沒有看起來很舒服的感覺。好吧,讓我開始盤它吧!

1.首先我先去寫了一個基類,用來創建一個新的request并把它加入到volley內部封裝的請求隊列中,代碼如下:

public abstract class AuthenticatedRequestBase<T> extends Request<T> { private final static String TAG = "AuthenticatedRequestBase"; private static final int TIME_OUT = 30000; private static final int MAX_RETRIES = 1; private static final float BACKOFF_MULT = 2f; protected Context mContext; protected RequestQueue mRequestQueue; /**  * 創建新的請求,并把請求加入到請求隊列requestQueue中  *  * @param method  * @param url  * @param cache  * @param errorListener  */ @SuppressLint("LongLogTag") public AuthenticatedRequestBase(int method, String url, boolean cache, Response.ErrorListener errorListener) {  super(method, url, errorListener);  //this.setShouldCache(cache);  this.setRetryPolicy(new DefaultRetryPolicy(    TIME_OUT,    MAX_RETRIES,    BACKOFF_MULT));  mRequestQueue = YZ.getInstance().getRequestQueue();  if (mRequestQueue == null) {   throw new IllegalArgumentException("mRequestQueue can't be null");  }  mContext = YZ.getInstance().getContext();  if (mContext == null) {   throw new IllegalArgumentException("mContext can't be null");  }  //如果重新發出服務器請求的時候,需要清除之前的緩存。  if (!cache) {   Cache volleyCache = mRequestQueue.getCache();   Cache.Entry cacheEntry = volleyCache.get(url);   if (cacheEntry != null) {    volleyCache.remove(url);    Log.d(TAG, "remove volley cache:" + url);   }  }  mRequestQueue.add(this); } /**  * 重寫這個方法,可以在http請求頭里面加入token,客戶端能接受的數據類型  *  * @return  * @throws AuthFailureError  */ @CallSuper @Override public Map<String, String> getHeaders() throws AuthFailureError {  Map<String, String> headers = new HashMap<>();  String token = "............";  //headers.put("Authorization", "bearer " + token);  //針對Get方法,申明接受的enum類型  // headers.put("Accept", "charset=utf-8");  return headers; } /**  * 網絡錯誤問題統一處理  *  * @param volleyError  * @return  */ @CallSuper @Override protected VolleyError parseNetworkError(VolleyError volleyError) {  return super.parseNetworkError(volleyError); }}

代碼注釋比較清晰,就不在贅述。

2.以get方法為例,新建一個GetRequest去繼承這個基類,并出解析結果:

public class GetRequest<TResponse> extends AuthenticatedRequestBase<TResponse> { private final Response.Listener<TResponse> listener; private final Class<TResponse> clazz; private final static String TAG = "GetRequest"; private String mUrl; private NetCallback<TResponse> cb; private boolean cacheHit; public GetRequest(String url, Class<TResponse> clazz, boolean cache, NetCallback<TResponse> callback) {  super(Request.Method.GET, url, cache, callback.getErrorListener());  this.listener = callback.getSuccessListener();  this.clazz = clazz;  this.mUrl = url;  this.cb = callback;  //無網絡時300ms后返回callback  if (!NetUtils.isConnect(mContext) && mRequestQueue.getCache().get(url) == null) {   Handler handler = new Handler();   handler.postDelayed(new Runnable() {    @Override    public void run() {     cb.OnNetworkOff();    }   }, 300);  } } /**  * 這個是緩存的標記,與本地緩存相關  * @param tag  */ @Override public void addMarker(String tag) {  super.addMarker(tag);  cacheHit = tag.equals("cache-hit"); } @Override protected Response<TResponse> parseNetworkResponse(NetworkResponse response) {  Gson gson = new Gson();  //無網絡時,使用本地緩存,通過url去匹配緩存,volley sdk是通過url創建不同的文件來實現緩存的  if (!NetUtils.isConnect(mContext) && mRequestQueue.getCache().get(mUrl) != null) {   String json = new String(mRequestQueue.getCache().get(mUrl).data);   Log.d(TAG, "url==" + mUrl + ",json" + json);   cb.fResponseCacheStatus = ResponseCacheStatus.StaleFromCache;   return Response.success(gson.fromJson(json, clazz), parseCacheHeaders(response));  }  //數據是否有更新  try {   if (response.statusCode == 304) {    //服務端返回緩存數據    cb.fResponseCacheStatus = ResponseCacheStatus.NotModifiedFromServer;   } else if (response.statusCode == 200) {    if (cacheHit) {     //使用本地緩存     cb.fResponseCacheStatus = ResponseCacheStatus.FreshFromCache;    } else {     //使用服務端更新數據     cb.fResponseCacheStatus = ResponseCacheStatus.NewFromServer;    }   } else {    cb.fResponseCacheStatus = ResponseCacheStatus.NewFromServer;   }   Log.d(TAG, "fResponseCacheStatus = " + cb.fResponseCacheStatus);   String json = new String(response.data, parseCharset(response.headers));   return Response.success(gson.fromJson(json, clazz), parseCacheHeaders(response));  } catch (UnsupportedEncodingException | JsonSyntaxException e) {   return Response.error(new ParseError(e));  } } @Override protected void deliverResponse(TResponse response) {  listener.onResponse(response); } @Override protected VolleyError parseNetworkError(VolleyError volleyError) {  return super.parseNetworkError(volleyError); }}

3.上面只做了返回成功的處理方式,返回失敗時由NetCallback內部統一處理:

@UiThreadpublic abstract class NetCallback<TResponse> { public ResponseCacheStatus fResponseCacheStatus = ResponseCacheStatus.NewFromServer; private String TAG = this.getClass().getSimpleName(); public boolean enableAutomaticToastOnError = true; public NetCallback() { } public NetCallback(boolean enableAutomaticToastOnError) {  this.enableAutomaticToastOnError = enableAutomaticToastOnError; } public abstract void OnSuccess(TResponse result); public abstract void OnError(RestfulError error); public void OnNetworkOff() {  //do nothing ,use it according to requirement } public Response.Listener<TResponse> getSuccessListener() {  return new Response.Listener<TResponse>() {   @Override   public void onResponse(TResponse result) {    OnSuccess(result);   }  }; } public Response.ErrorListener getErrorListener() {  return new Response.ErrorListener() {   @Override   public void onErrorResponse(VolleyError volleyError) {    if (volleyError instanceof TimeoutError) {     Log.e(TAG, "networkResponse == null");     //volley TimeoutError     OnError(new RestfulError());    }    if (volleyError.networkResponse != null) {     int statusCode = volleyError.networkResponse.statusCode;     String errorMessage = new String(volleyError.networkResponse.data);     switch (statusCode) {      case 401:       //post a Permission authentication failed event       break;      default:       Log.d(TAG, "errorMessage =" + errorMessage);       try {        RestfulError error = new Gson().fromJson(errorMessage, RestfulError.class);        if (enableAutomaticToastOnError && error.getCode() != null) {         //toast(error.ExceptionMessage); //toast it in main thread        }        OnError(error);       } catch (Exception e) {        OnError(new RestfulError());        Log.d(TAG, "e =" + e.toString());       }       break;     }    }   }  }; }}

4.注意到沒有,在AuthenticatedRequestBase內部有一個環境類YZ,主要負責獲取項目主程序中的context和請求隊列:

public class YZ implements AppRequestQueue { private static final int DEFAULT_VOLLEY_CACHE_SIZE = 100 * 1024 * 1024; private Context context; private int cacheSize; private YZ() { } @Override public RequestQueue getRequestQueue() {  return Volley.newRequestQueue(context, cacheSize); } public Context getContext() {  return context; } private static class SingletonHolder {  private static YZ instance = new YZ(); } public static YZ getInstance() {  return SingletonHolder.instance; } /**  * need a app context  *  * @param appContext  */ public void init(final Context appContext) {  init(appContext, DEFAULT_VOLLEY_CACHE_SIZE); } /**  * @param appContext  * @param cacheSize  */ public void init(final Context appContext, final int cacheSize) {  this.context = appContext;  this.cacheSize = cacheSize; }}

這個類需要在app的application中初始化:

public class BaseApp extends Application { public String TAG = this.getClass().getSimpleName(); public static Context applicationContext; public static Executor threadPool; public static final int THREAD_POOL_SIZE = 3; public static final boolean isDebug = BuildConfig.BUILD_TYPE.equals("debug"); @Override public void onCreate() {  super.onCreate();  applicationContext = getApplicationContext();  threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);  initNet(); } private void initNet() {  YZ.getInstance().init(this); } public Context getInstance() {  return applicationContext; }}

4.現在可以開始外部封裝啦。

public class NewsApi { public static void getInfo(NetCallback<News> callback) {  new GetRequest<>(INetConstant.NEWS, News.class, true, callback); }}

還有一點,volley的緩存實現需要服務端配合在http請求的Cache-control: max-age配置支持緩存,并設定好緩存時間,否則無法生效。

最后貼一張效果圖:

Android,volley,封裝

圖片發自簡書App

到此結束,后期還會進行優化,代碼在[github] (https://github.com/daydaydate/sample)。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧美一级免费高清 | lutube成人福利在线观看污 | 成人毛片100部 | 午夜精品福利在线观看 | 福利在线小视频 | 中国美女一级黄色片 | 久草在线视频在线 | 香蕉视频99 | 久久综合艹 | 国产福利视频在线观看 | 欧美在线 | 亚洲 | 3xxx | 日韩视频在线一区二区三区 | 国产99视频在线观看 | 久久久久久久一区二区 | 成人午夜毛片 | 精品国产91久久久久久 | 三人弄娇妻高潮3p视频 | 国产亚洲精品成人 | 在线成人影视 | 久久精品国产99久久久古代 | 亚洲精品一二三区 | 精品国产91久久久久久久 | 中文字幕免费在线看 | 99热高清| 一区二区三区欧美在线观看 | 欧美日韩亚洲在线观看 | 成码无人av片在线观看网站 | 91av在线免费视频 | 黄色高清免费网站 | 黄色一级片在线免费观看 | 日本中文字幕电影在线观看 | 黄色三级三级三级 | 国产精品久久久久久影院8一贰佰 | 91久久国产露脸精品免费 | 好吊一区二区三区 | 激情久久一区二区 | 欧美成人高清在线 | 精品一区二区三区欧美 | 亚洲午夜影院在线观看 | 天天看天天摸天天操 |