Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android網絡開源框架volley(五)——volley的一些細節

android網絡開源框架volley(五)——volley的一些細節

編輯:關於Android編程

最近又把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的總結都記錄在此。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved