APP開發(fā)公司分享Volley網(wǎng)絡(luò)庫的使用,為了使用方便,可以對Volley庫提供的類和方法進行二次封裝,深圳APP開發(fā)公司歸納整理其代碼如下所示。
public class JsonRequest extends JsonObjectRequest { String cookieString; public JsonRequest( String url, JSONObject jsonRequest, Response. ErrorListener errorListener) { super( url, jsonRequest, listener, errorListener); } //自定義向服務(wù)器發(fā)送的頭字段數(shù)據(jù) @ Override public Map< String, String> getHeaders() throws AuthFailureError { HashMap< String, String> headers = new HashMap< String, String>(); // 標示是Android APP向服務(wù)器發(fā)起請求 headers. put(" AppKey", "Android"); // 設(shè)置 User- Agent 的內(nèi)容為 APP 的包名和版本信息,標示是哪個APP向服務(wù)器發(fā)起請求 String packageName = context. getPackageName(); PackageInfo info = context. getPackageManager(). getPackageInfo( packageName, 0); userAgent = packageName + "/" + info. versionCode; headers. put(" User- Agent", userAgent ); //把服務(wù)器返回 給 APP 的 Cookie 信息, 添加到 PP發(fā)給服務(wù)器的頭信息中, 標示訪問服務(wù)器的客戶身份 headers. put(" Cookie", cookieString); return headers; } @ Override protected Response< JSONObject> parseNetworkResponse( NetworkResponse response) { try { String jsonString = new String( response. data, HttpHeaderParser. parseCharset( response. headers, PROTOCOL_ CHARSET)); // 獲取服務(wù)器返回給APP的Cookie信息 Map< String, String> headers = response. headers; cookieString = headers. get(" Set- Cookie"); // 解析服務(wù)器返回的 cookie 信息,從中獲取 SessionID String sessionId = parseVooleyCookie( cookies); return Response. success( new JSONObject( jsonString), HttpHeaderParser. parseCacheHeaders( response)); } catch (UnsupportedEncodingException e) { return Response. error( new ParseError( e)); } catch (JSONException je) { return Response. error( new ParseError( je)); }
} // 解析 cookie 數(shù)據(jù) public String parseVooleyCookie( String cookie) { StringBuilder sb = new StringBuilder(); String[] cookievalues = cookie. split(";"); for (int j = 0; j < cookievalues. length; j++) { String[] keyPair = cookievalues[ j]. split("/"); for (int i = 0; i < keyPair. length; i++) { if (keyPair[ 0]. contains(" session_ id")) { sb. append( keyPair[ 0]); sb. append(";"); break; } } } return sb. toString(); } }
使用OkHttp3作為Volley庫的HTTP協(xié)議棧,需要實現(xiàn)HttpStack里定義的接口方法。APP開發(fā)公司整理協(xié)議棧的具體代碼如下:
public class OkHttp3Stack implements HttpStack {
private final OkHttpClient mClient; public OkHttp3Stack( OkHttpClient client) { this. mClient = client; } @ Override public HttpResponse performRequest( Request<?> request, Map< String, String> additionalHeaders) throws IOException, AuthFailureError { int timeoutMs = request. getTimeoutMs(); OkHttpClient client = mClient. 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 (final String name : headers. 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; } 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"); } }
還需增加一個類,提供其他模塊調(diào)用Volley庫的接口方法。
public class NetworkManager { private static NetworkManager mInstance; private RequestQueue mRequestQueue; private static Context mCtx; private NetworkManager( Context context) { mCtx = context; mRequestQueue = getRequestQueue(); } // 使用單列模式創(chuàng)建類的實例 public static synchronized NetworkManager getInstance( Context context) { if (mInstance == null) { mInstance = new NetworkManager( context); } return mInstance; } public RequestQueue getRequestQueue() { if (mRequestQueue == null) { // 設(shè)置 使用 OkHttp3 作為 HTTP 協(xié)議棧 mRequestQueue = Volley. newRequestQueue( mCtx, new
OkHttp3Stack( new OkHttpClient())); } return mRequestQueue; } private < T> Request< T> add( Request< T> request) { return mRequestQueue. add( request);// 添加請求到隊列 } /** * 創(chuàng)建 JSON 格式的請求數(shù)據(jù) * */ public void JsonRequest( Object tag, String url, JSONObject jsonObject, Response. Listener< JSONObject> listener, Response. ErrorListener errorListener) { JsonRequest jsonRequest; jsonRequest = new JsonRequest( url, jsonObject, listener, errorListener); jsonRequest. setTag( tag); add( jsonRequest); }
/** * 取消請求 * */ public void cancel( Object tag) { mRequestQueue. cancelAll( tag); } }
函數(shù)調(diào)用方式如下:
NetworkManager. getInstance( EamApplication. getContext()). JsonRequest( TAG, baseUrl + url, jsonObject, new Response. Listener< JSONObject>() { @ Override public void onResponse( JSONObject jsonObject) { Log. v( TAG, "response json 對象: " + jsonObject. toString()); } }, new Response. ErrorListener() { @ Override public void onErrorResponse( VolleyError error) { Log. e( TAG, error. getMessage(), error);
} });
在創(chuàng)建網(wǎng)絡(luò)對象實例時,使用Application級別的Context,保證實例的生命周期與APP的生命周期一樣。好了,APP開發(fā)公司本文就“開發(fā)APP對于怎樣封裝Volley網(wǎng)絡(luò)庫代碼詳解”實操知識分享就到這里,謝謝關(guān)注,博納網(wǎng)絡(luò)編輯整理。