OkDownload下载异常ResumeFailedException: Resume failed because of RESPONSE_PRECONDITION_FAILED

OkDownload下载异常ResumeFailedException: Resume failed because of RESPONSE_PRECONDITION_FAILED

异常log日志

 com.liulishuo.okdownload.core.exception.ResumeFailedException: Resume failed because of RESPONSE_PRECONDITION_FAILED
 	at com.liulishuo.okdownload.core.download.DownloadStrategy$ResumeAvailableResponseCheck.inspect(DownloadStrategy.java:297)
 	at com.liulishuo.okdownload.core.interceptor.connect.HeaderInterceptor.interceptConnect(HeaderInterceptor.java:103)
 	at com.liulishuo.okdownload.core.download.DownloadChain.processConnect(DownloadChain.java:215)
 	at com.liulishuo.okdownload.core.interceptor.BreakpointInterceptor.interceptConnect(BreakpointInterceptor.java:48)
 	at com.liulishuo.okdownload.core.download.DownloadChain.processConnect(DownloadChain.java:215)
 	at com.liulishuo.okdownload.core.interceptor.RetryInterceptor.interceptConnect(RetryInterceptor.java:40)
	at com.liulishuo.okdownload.core.download.DownloadChain.processConnect(DownloadChain.java:215)
	at com.liulishuo.okdownload.core.download.DownloadChain.start(DownloadChain.java:180)
	at com.liulishuo.okdownload.core.download.DownloadChain.run(DownloadChain.java:247)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
	at java.lang.Thread.run(Thread.java:764)

原因:

可能是请求header中缺少If-Modified-Since

注: Last-Modified 与If-Modified-Since 都是标准的HTTP请求头标签,用于记录页面的最后修改时间。

解决方案

排除"If-Match"请求头

OkDownload初始化
  OkDownload.setSingletonInstance(new OkDownload.Builder(this)
                .connectionFactory(new NoEtagConnection.Factory())
                .build());
NoEtagConnection
class NoEtagConnection private constructor(
    private val client: OkHttpClient,
    private val requestBuilder: Request.Builder
) : DownloadConnection, Connected {

    private var request: Request? = null
    var response: Response? = null

    private constructor(client: OkHttpClient, url: String) : this(
        client,
        Request.Builder().url(url)
    )

    override fun addHeader(name: String, value: String) {
        if ("If-Match" == name) {
            return
        }
        requestBuilder.addHeader(name, value)
    }

    @Throws(IOException::class)
    override fun execute(): Connected {
        request = requestBuilder.build().apply {
            response = client.newCall(this).execute()
        }
        return this
    }

    override fun release() {
        response?.close()
        request = null
        response = null
    }

    override fun getRequestProperties(): Map<String, List<String>> = request?.headers?.toMultimap()
        ?: let { requestBuilder.build().headers.toMultimap() }

    override fun getRequestProperty(key: String): String? =
        request?.header(key) ?: requestBuilder.build().header(key)

    @Throws(IOException::class)
    override fun getResponseCode(): Int =
        response?.code ?: throw IOException("Please invoke execute first!")

    @Throws(IOException::class)
    override fun getInputStream(): InputStream = (response?.let {
        it.body ?: throw IOException("no body found on response!")
    } ?: throw IOException("Please invoke execute first!")).byteStream()

    @Throws(ProtocolException::class)
    override fun setRequestMethod(method: String): Boolean {
        requestBuilder.method(method, null)
        return true
    }

    override fun getResponseHeaderFields(): Map<String, List<String>>? =
        response?.headers?.toMultimap()

    override fun getResponseHeaderField(name: String): String? = response?.header(name)

    override fun getRedirectLocation(): String? {
        val priorRes = response?.priorResponse
        
        return priorRes?.let {
            if (response?.isSuccessful == true && RedirectUtil.isRedirect(it.code)) response?.request?.url.toString() else null
        }
    }

    class Factory : DownloadConnection.Factory {
        private var clientBuilder: OkHttpClient.Builder? = null

        fun setBuilder(builder: OkHttpClient.Builder?): Factory {
            clientBuilder = builder
            return this
        }

        fun builder(): OkHttpClient.Builder {
            return clientBuilder ?: OkHttpClient.Builder()
        }

        @Throws(IOException::class)
        override fun create(url: String): DownloadConnection {
            return NoEtagConnection(builder().build(), url)
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值