Search in sources :

Example 1 with HttpRetryHandler

use of org.xutils.http.app.HttpRetryHandler in project xUtils3 by wyouflf.

the class HttpTask method doBackground.

@Override
@SuppressWarnings("unchecked")
protected ResultType doBackground() throws Throwable {
    if (this.isCancelled()) {
        throw new Callback.CancelledException("cancelled before request");
    }
    // 初始化请求参数
    ResultType result = null;
    resolveLoadType();
    request = createNewRequest();
    checkDownloadTask();
    // retry 初始化
    boolean retry = true;
    int retryCount = 0;
    Throwable exception = null;
    HttpRetryHandler retryHandler = this.params.getHttpRetryHandler();
    if (retryHandler == null) {
        retryHandler = new HttpRetryHandler();
    }
    retryHandler.setMaxRetryCount(this.params.getMaxRetryCount());
    if (this.isCancelled()) {
        throw new Callback.CancelledException("cancelled before request");
    }
    // 检查缓存
    Object cacheResult = null;
    if (cacheCallback != null && HttpMethod.permitsCache(params.getMethod())) {
        // 尝试从缓存获取结果, 并为请求头加入缓存控制参数.
        try {
            clearRawResult();
            LogUtil.d("load cache: " + this.request.getRequestUri());
            rawResult = this.request.loadResultFromCache();
        } catch (Throwable ex) {
            LogUtil.w("load disk cache error", ex);
        }
        if (this.isCancelled()) {
            clearRawResult();
            throw new Callback.CancelledException("cancelled before request");
        }
        if (rawResult != null) {
            if (prepareCallback != null) {
                try {
                    cacheResult = prepareCallback.prepare(rawResult);
                } catch (Throwable ex) {
                    cacheResult = null;
                    LogUtil.w("prepare disk cache error", ex);
                } finally {
                    clearRawResult();
                }
            } else {
                cacheResult = rawResult;
            }
            if (this.isCancelled()) {
                throw new Callback.CancelledException("cancelled before request");
            }
            if (cacheResult != null) {
                // 同步等待是否信任缓存
                this.update(FLAG_CACHE, cacheResult);
                synchronized (cacheLock) {
                    while (trustCache == null) {
                        try {
                            cacheLock.wait();
                        } catch (InterruptedException iex) {
                            throw new Callback.CancelledException("cancelled before request");
                        } catch (Throwable ignored) {
                        }
                    }
                }
                // 处理完成
                if (trustCache) {
                    return null;
                }
            }
        }
    }
    if (trustCache == null) {
        trustCache = false;
    }
    if (cacheResult == null) {
        this.request.clearCacheHeader();
    }
    // 判断请求的缓存策略
    if (callback instanceof Callback.ProxyCacheCallback) {
        if (((Callback.ProxyCacheCallback) callback).onlyCache()) {
            return null;
        }
    }
    // 发起请求
    retry = true;
    while (retry) {
        retry = false;
        try {
            if (this.isCancelled()) {
                throw new Callback.CancelledException("cancelled before request");
            }
            // 由loader发起请求, 拿到结果.
            // retry 前关闭上次请求
            this.request.close();
            try {
                clearRawResult();
                // 开始请求工作
                LogUtil.d("load: " + this.request.getRequestUri());
                requestWorker = new RequestWorker();
                requestWorker.request();
                if (requestWorker.ex != null) {
                    throw requestWorker.ex;
                }
                rawResult = requestWorker.result;
            } catch (Throwable ex) {
                clearRawResult();
                if (this.isCancelled()) {
                    throw new Callback.CancelledException("cancelled during request");
                } else {
                    throw ex;
                }
            }
            if (prepareCallback != null) {
                if (this.isCancelled()) {
                    throw new Callback.CancelledException("cancelled before request");
                }
                try {
                    result = (ResultType) prepareCallback.prepare(rawResult);
                } finally {
                    clearRawResult();
                }
            } else {
                result = (ResultType) rawResult;
            }
            // 保存缓存
            if (cacheCallback != null && HttpMethod.permitsCache(params.getMethod())) {
                this.request.save2Cache();
            }
            if (this.isCancelled()) {
                throw new Callback.CancelledException("cancelled after request");
            }
        } catch (HttpRedirectException redirectEx) {
            retry = true;
            LogUtil.w("Http Redirect:" + params.getUri());
        } catch (Throwable ex) {
            switch(this.request.getResponseCode()) {
                // empty content
                case 204:
                // empty content
                case 205:
                case // disk cache is valid.
                304:
                    return null;
                default:
                    {
                        exception = ex;
                        if (this.isCancelled() && !(exception instanceof Callback.CancelledException)) {
                            exception = new Callback.CancelledException("canceled by user");
                        }
                        retry = retryHandler.canRetry(this.request, exception, ++retryCount);
                    }
            }
        }
    }
    if (exception != null && result == null && !trustCache) {
        hasException = true;
        throw exception;
    }
    return result;
}
Also used : HttpRedirectException(org.xutils.ex.HttpRedirectException) HttpRetryHandler(org.xutils.http.app.HttpRetryHandler) Callback(org.xutils.common.Callback)

Aggregations

Callback (org.xutils.common.Callback)1 HttpRedirectException (org.xutils.ex.HttpRedirectException)1 HttpRetryHandler (org.xutils.http.app.HttpRetryHandler)1