編輯:關於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 Response parseNetworkResponse(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開發之實現圖片自動滾動顯示標簽的ViewPager
Android中實現圖片自動滾動的效果非常的常見,我們可以自己動畫去實現功能。但是在Android中提供了一個ViewPager類,實現了滾動效果,在Android的ex
華為榮耀note8怎麼使用智能短信功能 榮耀note8設置智能短信
傳統的短信已經逐漸被各種微信、QQ諸如此類的社交軟件所取代,我們能用到的短信最大的功能也無外乎是驗證碼、充值或是購票等等。不過華為榮耀Note8的推出,卻改
layout_weight屬性圖解
layout_height的作用:首先按照聲明的尺寸分配,剩余的空間再按照layout_weight進行分配一平均分配:代碼:<code class="h
Android自定義View時添加自己的監聽器
監聽器在Java中非常常用,在自定義控件時可能根據自己的需要去監聽一些數據的改變,這時就需要我們自己去寫監聽器,Java中的監聽器實際上就是C++中的回調