/*
* Copyright (c) 2014, Android Open Source Project,张涛.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kymjs.kjframe.http;
import android.os.Process;
import org.kymjs.kjframe.KJHttp;
import org.kymjs.kjframe.bitmap.Persistence;
import org.kymjs.kjframe.utils.KJLoger;
import java.util.concurrent.BlockingQueue;
/**
* 缓存调度器
* 工作描述: 缓存逻辑同样也采用责任链模式,参考注释{@link KJHttp },
* 由缓存任务队列CacheQueue,缓存调度器CacheDispatcher,缓存器Cache组成
* 调度器不停的从CacheQueue中取request,并把这个request尝试从缓存器中获取缓存响应。<br>
* 如果缓存器有有效且及时的缓存则直接返回缓存;<br>
* 如果缓存器有有效但待刷新的有效缓存,则交给分发器去分发一次中介相应,并再去添加到工作队列中执行网络请求获取最新的数据;<br>
* 如果缓存器中没有有效缓存,则把请求添加到mNetworkQueue工作队列中去执行网络请求;<br>
*
* @author kymjs (http://www.kymjs.com/) .
*/
public class CacheDispatcher extends Thread {
private final BlockingQueue<Request<?>> mCacheQueue; // 缓存队列
private final BlockingQueue<Request<?>> mNetworkQueue; // 用于执行网络请求的工作队列
private final Cache mCache; // 缓存器
private final Delivery mDelivery; // 分发器
private final HttpConfig mConfig; // 配置器
private volatile boolean mQuit = false;
/**
* 创建分发器(必须手动调用star()方法启动分发任务)
*
* @param cacheQueue 缓存队列
* @param networkQueue 正在执行的队列
* @param config 配置器
*/
public CacheDispatcher(BlockingQueue<Request<?>> cacheQueue,
BlockingQueue<Request<?>> networkQueue, HttpConfig config) {
mCacheQueue = cacheQueue;
mNetworkQueue = networkQueue;
mCache = HttpConfig.mCache;
mDelivery = config.mDelivery;
mConfig = config;
}
/**
* 强制退出
*/
public void quit() {
mQuit = true;
interrupt();
}
/**
* 工作在阻塞态
*/
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
mCache.initialize();
while (true) {
try {
final Request<?> request = mCacheQueue.take();
if (request.isCanceled()) {
request.finish("cache-discard-canceled");
continue;
}
Cache.Entry entry = mCache.get(request.getCacheKey());
if (entry == null) { // 如果没有缓存,去网络请求
mNetworkQueue.put(request);
continue;
}
// 如果缓存过期,去网络请求,图片缓存永久有效
if (entry.isExpired() && !(request instanceof Persistence)) {
request.setCacheEntry(entry);
mNetworkQueue.put(request);
continue;
}
// 从缓存返回数据
Response<?> response = request
.parseNetworkResponse(new NetworkResponse(entry.data,
entry.responseHeaders));
KJLoger.debugLog("CacheDispatcher:", "http resopnd from cache");
if (mConfig.useDelayCache) {
sleep(mConfig.delayTime);
}
mDelivery.postResponse(request, response);
} catch (InterruptedException e) {
if (mQuit) {
return;
} else {
continue;
}
}
}
}
}