本篇文章給大家分享的是有關(guān)怎么在Android中對(duì)volley進(jìn)行封裝,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、璧山ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的璧山網(wǎng)站制作公司
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() { @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() { @Override public void OnSuccess(final News result) { mAdapter.setData(result.getResult().getData()); } @Override public void OnError(RestfulError error) { } }); }
有沒(méi)有看起來(lái)很舒服的感覺(jué)。好吧,讓我開(kāi)始盤(pán)它吧!
1.首先我先去寫(xiě)了一個(gè)基類,用來(lái)創(chuàng)建一個(gè)新的request并把它加入到volley內(nèi)部封裝的請(qǐng)求隊(duì)列中,代碼如下:
public abstract class AuthenticatedRequestBaseextends Request { 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; /** * 創(chuàng)建新的請(qǐng)求,并把請(qǐng)求加入到請(qǐng)求隊(duì)列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"); } //如果重新發(fā)出服務(wù)器請(qǐng)求的時(shí)候,需要清除之前的緩存。 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); } /** * 重寫(xiě)這個(gè)方法,可以在http請(qǐng)求頭里面加入token,客戶端能接受的數(shù)據(jù)類型 * * @return * @throws AuthFailureError */ @CallSuper @Override public Map getHeaders() throws AuthFailureError { Map headers = new HashMap<>(); String token = "............"; //headers.put("Authorization", "bearer " + token); //針對(duì)Get方法,申明接受的enum類型 // headers.put("Accept", "charset=utf-8"); return headers; } /** * 網(wǎng)絡(luò)錯(cuò)誤問(wèn)題統(tǒng)一處理 * * @param volleyError * @return */ @CallSuper @Override protected VolleyError parseNetworkError(VolleyError volleyError) { return super.parseNetworkError(volleyError); } }
代碼注釋比較清晰,就不在贅述。
2.以get方法為例,新建一個(gè)GetRequest去繼承這個(gè)基類,并出解析結(jié)果:
public class GetRequestextends AuthenticatedRequestBase { private final Response.Listener listener; private final Class clazz; private final static String TAG = "GetRequest"; private String mUrl; private NetCallback cb; private boolean cacheHit; public GetRequest(String url, Class clazz, boolean cache, NetCallback callback) { super(Request.Method.GET, url, cache, callback.getErrorListener()); this.listener = callback.getSuccessListener(); this.clazz = clazz; this.mUrl = url; this.cb = callback; //無(wú)網(wǎng)絡(luò)時(shí)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); } } /** * 這個(gè)是緩存的標(biāo)記,與本地緩存相關(guān) * @param tag */ @Override public void addMarker(String tag) { super.addMarker(tag); cacheHit = tag.equals("cache-hit"); } @Override protected Response parseNetworkResponse(NetworkResponse response) { Gson gson = new Gson(); //無(wú)網(wǎng)絡(luò)時(shí),使用本地緩存,通過(guò)url去匹配緩存,volley sdk是通過(guò)url創(chuàng)建不同的文件來(lái)實(shí)現(xiàn)緩存的 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)); } //數(shù)據(jù)是否有更新 try { if (response.statusCode == 304) { //服務(wù)端返回緩存數(shù)據(jù) cb.fResponseCacheStatus = ResponseCacheStatus.NotModifiedFromServer; } else if (response.statusCode == 200) { if (cacheHit) { //使用本地緩存 cb.fResponseCacheStatus = ResponseCacheStatus.FreshFromCache; } else { //使用服務(wù)端更新數(shù)據(jù) 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.上面只做了返回成功的處理方式,返回失敗時(shí)由NetCallback內(nèi)部統(tǒng)一處理:
@UiThread public abstract class NetCallback{ 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 getSuccessListener() { return new Response.Listener () { @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.注意到?jīng)]有,在AuthenticatedRequestBase內(nèi)部有一個(gè)環(huán)境類YZ,主要負(fù)責(zé)獲取項(xiàng)目主程序中的context和請(qǐng)求隊(duì)列:
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; } }
這個(gè)類需要在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.現(xiàn)在可以開(kāi)始外部封裝啦。
public class NewsApi { public static void getInfo(NetCallbackcallback) { new GetRequest<>(INetConstant.NEWS, News.class, true, callback); } }
以上就是怎么在Android中對(duì)volley進(jìn)行封裝,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。