標籤:android volley delete http
最近又把volley拿出來整理了下。之前沒有遇到過的一些小問題又來了,在此記錄下:
1、HttpUrlConnection DELETE 方式無法添加body的問題:java.net.ProtocolException: DELETE does not support writing
這個可以算是一個系統級的bug,為什麼這麼說,請看這裡,這個問題在java8中才得以解決。沒辦法直接過去,咱就繞過去。查看HttpUrlConnection,我們發現他是一個抽象類別,因此可以試試能不能通過它的其他實現來達到我們的目的。最終我們決定使用okhttp這個實現。地址為:https://github.com/square/okhttp。
接著我們還得去看看volley的源碼,由於我們的app相容的最低版本是4.0,因此我們知道最終調用的是HurlStack:
public static RequestQueue newRequestQueue(Context context, HttpStack 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)); } }... }
因此我們只需要將HurlStack的相關代碼修改即可,如下:
volley.java
public static RequestQueue newRequestQueue(Context context, HttpStack stack) {... if (stack == null) { if (Build.VERSION.SDK_INT >= 9) { // old way: stack = new HurlStack(); // http://square.github.io/okhttp/ stack = new HurlStack(null, null, new OkUrlFactory(new OkHttpClient())); } 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)); } }... }HurlStack.java
/** * An {@link HttpStack} based on {@link HttpURLConnection}. */public class HurlStack implements HttpStack { private final OkUrlFactory mOkUrlFactory; /** * @param urlRewriter Rewriter to use for request URLs * @param sslSocketFactory SSL factory to use for HTTPS connections * @param okUrlFactory solution delete body(https://github.com/square/okhttp) */ public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory, OkUrlFactory okUrlFactory) { mUrlRewriter = urlRewriter; mSslSocketFactory = sslSocketFactory; mOkUrlFactory = okUrlFactory; } /** * Create an {@link HttpURLConnection} for the specified {@code url}. */ protected HttpURLConnection createConnection(URL url) throws IOException {if(null != mOkUrlFactory){return mOkUrlFactory.open(url);} return (HttpURLConnection) url.openConnection(); } @SuppressWarnings("deprecation") /* package */ static void setConnectionParametersForRequest(HttpURLConnection connection, Request<?> request) throws IOException, AuthFailureError { switch (request.getMethod()) { ... case Method.DELETE: connection.setRequestMethod("DELETE"); addBodyIfExists(connection, request); break; ... default: throw new IllegalStateException("Unknown method type."); } }...}
2、關於(修改)volley的緩衝
volley有完整的一套緩衝機制。而目前我們想做個簡單的需求:部分介面(幾乎不會改動的)簡單的做一定時間的緩衝,研究了下代碼發現很容易修改達到自己的目的(有時間在分析下volley的緩衝機制,這個一定要做)。簡單來說修改一個地方:request.parseNetworkResponse中的
HttpHeaderParser(此處突然感慨volley的設計TMD靈活了,想怎麼改就怎麼改)。HttpHeaderParser修改後的代碼如下:
/** * 修改後的,使用者處理緩衝 */public class BHHttpHeaderParser { /** * Extracts a {@link Cache.Entry} from a {@link NetworkResponse}. * * @param response The network response to parse headers from * @return a cache entry for the given response, or null if the response is not cacheable. */ public static Cache.Entry parseCacheHeaders(NetworkResponse response, boolean isCustomCache) {... if(isCustomCache){ softExpire = now + Config.HTTP_CACHE_TTL; } else { if (hasCacheControl) { softExpire = now + maxAge * 1000; } else if (serverDate > 0 && serverExpires >= serverDate) { // Default semantic for Expire header in HTTP specification is softExpire. softExpire = now + (serverExpires - serverDate); } } Cache.Entry entry = new Cache.Entry(); entry.data = response.data; entry.etag = serverEtag; entry.softTtl = softExpire; entry.ttl = entry.softTtl; entry.serverDate = serverDate; entry.responseHeaders = headers; return entry; }...}此處大家可以發現,我們主要是根據自訂的變數決定如何修改cache的TTL來達到自己的目的。
以後有其他關於volley的總結都記錄在此。
android網路開源架構volley(五)——volley的一些細節