編輯:關於Android編程
Volley是Android系統下的一個網絡通信庫,為Android提供簡單快速的網絡操作(Volley:Esay, Fast Networking for Android),下面是它的結構:
vc34wue1xLv5tKGy2df3o7rH68fzus3P7NOmo6zSssrH1+67+bG+tcS4xcTuoaO/zbuntsu3orP2x+vH86Ost/7O8bbLt7W72M/s06a1xNfWvdrK/b7do6y/zbuntsu94s72tcO1vc/r0qq1xL3hufuho1ZvbGxledT1w7TJ6LzG1eLQqbv5sb61xLjFxO6jvzwvcD4KPHA+0ruhotfpvP48L3A+CjxwPjGhok5ldHdvcms8L3A+CjxwPs34wuey2df3tcS2qNLlo6y0q8jrx+vH81JlcXVlc3SjrLXDtb3P7NOmTmV0d29ya1Jlc3BvbnNlPC9wPgo8cD48L3A+CjxwcmUgY2xhc3M9"brush:java;">public interface Network {
/**
* Performs the specified request.
* @param request Request to process
* @return A {@link NetworkResponse} with data and caching metadata; will never be null
* @throws VolleyError on errors
*/
public NetworkResponse performRequest(Request> request) throws VolleyError;
}
2、Request
請求的定義,網絡請求的參數、地址等信息
public Request(int method, String url, Response.ErrorListener listener) { mMethod = method; mUrl = url; mErrorListener = listener; setRetryPolicy(new DefaultRetryPolicy()); mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url); }
一個是 parseNetworkResponse,就是說對於返回的數據,需要怎麼去解析,解析成什麼類型的數據。一個具體的請求,應該知道自己想要什麼結果,比如StringRequest就是將結果解析成String,而ImageRequest則是將結果解析成Bitmap;
另一個是 deliverResponse,用於解析完成後將結果傳遞出去。這裡傳入的是已經解析的結果,子類負責處理返回的解析結果,一般會在裡面通過listener返回到應用的場景下。
/** * Subclasses must implement this to parse the raw network response * and return an appropriate response type. This method will be * called from a worker thread. The response will not be delivered * if you return null. * @param response Response from the network * @return The parsed response, or null in the case of an error */ abstract protected ResponseparseNetworkResponse(NetworkResponse response); /** * Subclasses must implement this to perform delivery of the parsed * response to their listeners. The given response is guaranteed to * be non-null; responses that fail to parse are not delivered. * @param response The parsed response returned by * {@link #parseNetworkResponse(NetworkResponse)} */ abstract protected void deliverResponse(T response);
3、NetworkResponse
網絡請求通用返回結果,存儲在data中
public NetworkResponse(int statusCode, byte[] data, Mapheaders, boolean notModified) { this.statusCode = statusCode; this.data = data; this.headers = headers; this.notModified = notModified; }
4、Response
響應結果的封裝,最終結果result,緩存結構cacheEntry,出錯信息error
private Response(T result, Cache.Entry cacheEntry) { this.result = result; this.cacheEntry = cacheEntry; this.error = null; }
二、執行過程
有了上面的基本數據結構,之後就是考慮怎麼去操作這些結構,完成從請求到響應的整個過程。這裡是整個Volley最核心的部分,也是體現作者設計思想的部分,涉及到任務調度、異步處理等。
1、RequestQueue
請求隊列,所有請求都會通過RequestQueue的add方法加入到內部的隊列裡來等待處理,當請求結束得到響應結果後會調用finish方法將請求移出請求隊列。
RequestQueue中包含以下成員:
Cache 緩存結構,用於緩存響應結果;Network 網絡操作的實現NetworkDispatcher 網絡任務調度器CacheDispatcher 緩存任務調度器ResponseDelivery 響應投遞,用於將結果從工作線程轉移到UI線程 cacheQueue 緩存任務隊列networkQueue 網絡任務隊列RequestQueue完成兩項工作:
啟動、停止調度器:
/** * Starts the dispatchers in this queue. */ public void start() { stop(); // Make sure any currently running dispatchers are stopped. // Create the cache dispatcher and start it. mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery); mCacheDispatcher.start(); // Create network dispatchers (and corresponding threads) up to the pool size. for (int i = 0; i < mDispatchers.length; i++) { NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery); mDispatchers[i] = networkDispatcher; networkDispatcher.start(); } } /** * Stops the cache and network dispatchers. */ public void stop() { if (mCacheDispatcher != null) { mCacheDispatcher.quit(); } for (int i = 0; i < mDispatchers.length; i++) { if (mDispatchers[i] != null) { mDispatchers[i].quit(); } } }
publicRequest add(Request request) { // Tag the request as belonging to this queue and add it to the set of current requests. request.setRequestQueue(this); synchronized (mCurrentRequests) { mCurrentRequests.add(request); } // Process requests in the order they are added. request.setSequence(getSequenceNumber()); request.addMarker("add-to-queue"); // If the request is uncacheable, skip the cache queue and go straight to the network. if (!request.shouldCache()) { mNetworkQueue.add(request); return request; } // Insert request into stage if there's already a request with the same cache key in flight. synchronized (mWaitingRequests) { String cacheKey = request.getCacheKey(); if (mWaitingRequests.containsKey(cacheKey)) { // There is already a request in flight. Queue up. Queue > stagedRequests = mWaitingRequests.get(cacheKey); if (stagedRequests == null) { stagedRequests = new LinkedList >(); } stagedRequests.add(request); mWaitingRequests.put(cacheKey, stagedRequests); if (VolleyLog.DEBUG) { VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey); } } else { // Insert 'null' queue for this cacheKey, indicating there is now a request in // flight. mWaitingRequests.put(cacheKey, null); mCacheQueue.add(request); } return request; } }
2、CacheDispatcher,NetworkDispatcher
調度器是線程,隊列阻塞,有請求就執行,沒有就等待。對緩存調度器CacheDispatcher,如果在緩存中沒有找到響應結果,就會將請求添加到網絡調度器NetworkDispatcher中
while (true) { try { // Get a request from the cache triage queue, blocking until // at least one is available. final Request> request = mCacheQueue.take(); request.addMarker("cache-queue-take"); // If the request has been canceled, don't bother dispatching it. if (request.isCanceled()) { request.finish("cache-discard-canceled"); continue; } // Attempt to retrieve this item from cache. Cache.Entry entry = mCache.get(request.getCacheKey()); if (entry == null) { request.addMarker("cache-miss"); // Cache miss; send off to the network dispatcher. mNetworkQueue.put(request); continue; } // If it is completely expired, just send it to the network. if (entry.isExpired()) { request.addMarker("cache-hit-expired"); request.setCacheEntry(entry); mNetworkQueue.put(request); continue; } // We have a cache hit; parse its data for delivery back to the request. request.addMarker("cache-hit"); Response> response = request.parseNetworkResponse( new NetworkResponse(entry.data, entry.responseHeaders)); request.addMarker("cache-hit-parsed"); if (!entry.refreshNeeded()) { // Completely unexpired cache hit. Just deliver the response. mDelivery.postResponse(request, response); } else { // Soft-expired cache hit. We can deliver the cached response, // but we need to also send the request to the network for // refreshing. request.addMarker("cache-hit-refresh-needed"); request.setCacheEntry(entry); // Mark the response as intermediate. response.intermediate = true; // Post the intermediate response back to the user and have // the delivery then forward the request along to the network. mDelivery.postResponse(request, response, new Runnable() { @Override public void run() { try { mNetworkQueue.put(request); } catch (InterruptedException e) { // Not much we can do about this. } } }); }
Android中實現圖片自動滾動的效果非常的常見,我們可以自己動畫去實現功能。但是在Android中提供了一個ViewPager類,實現了滾動效果,在Android的ex
傳統的短信已經逐漸被各種微信、QQ諸如此類的社交軟件所取代,我們能用到的短信最大的功能也無外乎是驗證碼、充值或是購票等等。不過華為榮耀Note8的推出,卻改
layout_height的作用:首先按照聲明的尺寸分配,剩余的空間再按照layout_weight進行分配一平均分配:代碼:<code class="h
監聽器在Java中非常常用,在自定義控件時可能根據自己的需要去監聽一些數據的改變,這時就需要我們自己去寫監聽器,Java中的監聽器實際上就是C++中的回調