> 文档中心 > OkDownload下载异常ResumeFailedException: Resume failed because of RESPONSE_PRECONDITION_FAILED

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> = 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>? = 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) }    }}