Merge pull request #1781 from ag2s20150909/master

Cronet共用okhttp的线程池
pull/1785/head
kunfei 3 years ago committed by GitHub
commit 31fd74a3f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      app/src/main/java/io/legado/app/help/http/cronet/AbsCallBack.kt
  2. 14
      app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt
  3. 1
      app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt
  4. 8
      app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt
  5. 53
      app/src/main/java/io/legado/app/help/http/cronet/NewCallBack.kt
  6. 39
      app/src/main/java/io/legado/app/help/http/cronet/OldCallback.kt
  7. 4
      app/src/main/java/io/legado/app/utils/ThrowableExtensions.kt

@ -2,7 +2,7 @@ package io.legado.app.help.http.cronet
import io.legado.app.help.http.okHttpClient
import io.legado.app.utils.DebugLog
import io.legado.app.utils.rethrowAsIOException
import io.legado.app.utils.asIOException
import okhttp3.*
import okhttp3.EventListener
import okhttp3.MediaType.Companion.toMediaTypeOrNull
@ -27,12 +27,24 @@ abstract class AbsCallBack(
var mResponse: Response
var mException: IOException? = null
private var followCount = 0
@Throws(IOException::class)
abstract fun waitForDone(urlRequest: UrlRequest): Response
/**
* 当发生错误时通知子类终止阻塞抛出错误
* @param error
*/
abstract fun onError(error: IOException)
/**
* 请求成功后通知子类结束阻塞返回response
* @param response
*/
abstract fun onSuccess(response: Response)
override fun onRedirectReceived(
request: UrlRequest,
@ -41,10 +53,13 @@ abstract class AbsCallBack(
) {
if (followCount > MAX_FOLLOW_COUNT) {
request.cancel()
mException = IOException("Too many redirect")
onError(IOException("Too many redirect"))
return
}
if (mCall.isCanceled()) {
mException = IOException("Request Canceled")
onError(IOException("Request Canceled"))
request.cancel()
return
}
followCount += 1
val client = okHttpClient
@ -55,7 +70,7 @@ abstract class AbsCallBack(
} else if (okHttpClient.followRedirects) {
request.followRedirect()
} else {
mException = IOException("Too many redirect")
onError(IOException("Too many redirect"))
request.cancel()
}
}
@ -73,7 +88,7 @@ abstract class AbsCallBack(
}
@Throws(Exception::class)
@Throws(IOException::class)
override fun onReadCompleted(
request: UrlRequest,
info: UrlResponseInfo,
@ -83,7 +98,7 @@ abstract class AbsCallBack(
if (mCall.isCanceled()) {
request.cancel()
mException = IOException("Request Canceled")
onError(IOException("Request Canceled"))
}
byteBuffer.flip()
@ -91,9 +106,9 @@ abstract class AbsCallBack(
try {
buffer.write(byteBuffer)
} catch (e: IOException) {
DebugLog.i(javaClass.name, "IOException during ByteBuffer read. Details: ", e)
mException = IOException("IOException during ByteBuffer read. Details:", e)
throw e
DebugLog.e(javaClass.name, "IOException during ByteBuffer read. Details: ", e)
onError(IOException("IOException during ByteBuffer read. Details:", e))
return
}
byteBuffer.clear()
request.read(byteBuffer)
@ -108,7 +123,8 @@ abstract class AbsCallBack(
buffer.asResponseBody(contentType)
val newRequest = originalRequest.newBuilder().url(info.url).build()
this.mResponse = this.mResponse.newBuilder().body(responseBody).request(newRequest).build()
DebugLog.i(javaClass.simpleName, "end[${info.negotiatedProtocol}]${info.url}")
onSuccess(this.mResponse)
//DebugLog.i(javaClass.simpleName, "end[${info.negotiatedProtocol}]${info.url}")
eventListener?.callEnd(mCall)
if (responseCallback != null) {
@ -123,8 +139,8 @@ abstract class AbsCallBack(
//UrlResponseInfo可能为null
override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) {
DebugLog.i(javaClass.name, error.message.toString())
mException = error.rethrowAsIOException()
DebugLog.e(javaClass.name, error.message.toString())
onError(error.asIOException())
this.eventListener?.callFailed(mCall, error)
responseCallback?.onFailure(mCall, error)
}
@ -132,7 +148,7 @@ abstract class AbsCallBack(
override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
super.onCanceled(request, info)
this.eventListener?.callEnd(mCall)
mException = IOException("Cronet Request Canceled")
onError(IOException("Cronet Request Canceled"))
}

@ -2,6 +2,7 @@ package io.legado.app.help.http.cronet
import io.legado.app.constant.AppLog
import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.okHttpClient
import io.legado.app.utils.DebugLog
import okhttp3.Headers
import okhttp3.MediaType
@ -13,11 +14,8 @@ import org.chromium.net.UploadDataProviders
import org.chromium.net.UrlRequest
import splitties.init.appCtx
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
val executor: ExecutorService by lazy { Executors.newCachedThreadPool() }
//val executor: ExecutorService by lazy { Executors.newCachedThreadPool() }
val cronetEngine: ExperimentalCronetEngine? by lazy {
if (!AppConfig.isGooglePlay) {
@ -48,7 +46,11 @@ fun buildRequest(request: Request, callback: UrlRequest.Callback): UrlRequest? {
val url = request.url.toString()
val headers: Headers = request.headers
val requestBody = request.body
return cronetEngine?.newUrlRequestBuilder(url, callback, executor)?.apply {
return cronetEngine?.newUrlRequestBuilder(
url,
callback,
okHttpClient.dispatcher.executorService
)?.apply {
setHttpMethod(request.method)//设置
allowDirectExecutor()
headers.forEachIndexed { index, _ ->
@ -65,7 +67,7 @@ fun buildRequest(request: Request, callback: UrlRequest.Callback): UrlRequest? {
requestBody.writeTo(buffer)
setUploadDataProvider(
UploadDataProviders.create(buffer.readByteArray()),
executor
okHttpClient.dispatcher.executorService
)
}

@ -49,7 +49,6 @@ class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor {
OldCallback(request, call)
}
buildRequest(request, callBack)?.let {
it.start()
return callBack.waitForDone(it)
}
return null

@ -268,7 +268,8 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
return
}
download = true
executor.execute {
Coroutine.async {
val result = downloadFileIfNotExist(url, downloadTempFile)
DebugLog.d(javaClass.simpleName, "download result:$result")
//文件md5再次校验
@ -279,7 +280,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
downloadTempFile.deleteOnExit()
}
download = false
return@execute
return@async
}
DebugLog.d(javaClass.simpleName, "download success, copy to $destSuccessFile")
//下载成功拷贝文件
@ -289,6 +290,9 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
@Suppress("SameParameterValue")
deleteHistoryFile(parentFile!!, null)
}
// executor.execute {
//
// }
}
/**

@ -6,11 +6,8 @@ import androidx.annotation.RequiresApi
import okhttp3.Call
import okhttp3.Request
import okhttp3.Response
import org.chromium.net.CronetException
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
import java.io.IOException
import java.nio.ByteBuffer
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
@ -21,45 +18,29 @@ class NewCallBack(originalRequest: Request, mCall: Call) : AbsCallBack(originalR
@Throws(IOException::class)
override fun waitForDone(urlRequest: UrlRequest): Response {
return responseFuture.get(mCall.timeout().timeoutNanos(), TimeUnit.NANOSECONDS)
}
override fun onRedirectReceived(
request: UrlRequest,
info: UrlResponseInfo,
newLocationUrl: String
) {
super.onRedirectReceived(request, info, newLocationUrl)
if (mException != null) {
responseFuture.completeExceptionally(mException)
urlRequest.start()
return if (mCall.timeout().timeoutNanos() > 0) {
responseFuture.get(mCall.timeout().timeoutNanos(), TimeUnit.NANOSECONDS)
} else {
return responseFuture.get()
}
}
override fun onReadCompleted(
request: UrlRequest,
info: UrlResponseInfo,
byteBuffer: ByteBuffer
) {
super.onReadCompleted(request, info, byteBuffer)
if (mException != null) {
responseFuture.completeExceptionally(mException)
}
}
override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo) {
super.onSucceeded(request, info)
responseFuture.complete(mResponse)
}
override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) {
super.onFailed(request, info, error)
responseFuture.completeExceptionally(mException)
/**
* 当发生错误时通知子类终止阻塞抛出错误
* @param error
*/
override fun onError(error: IOException) {
responseFuture.completeExceptionally(error)
}
override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
super.onCanceled(request, info)
responseFuture.completeExceptionally(mException)
/**
* 请求成功后通知子类结束阻塞返回response
* @param response
*/
override fun onSuccess(response: Response) {
responseFuture.complete(response)
}

@ -4,20 +4,19 @@ import android.os.ConditionVariable
import okhttp3.Call
import okhttp3.Request
import okhttp3.Response
import org.chromium.net.CronetException
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
import java.io.IOException
import java.nio.ByteBuffer
class OldCallback(originalRequest: Request, mCall: Call) : AbsCallBack(originalRequest, mCall) {
private val mResponseCondition = ConditionVariable()
private var mException: IOException? = null
@Throws(IOException::class)
override fun waitForDone(urlRequest: UrlRequest): Response {
//获取okhttp call的完整请求的超时时间
val timeOutMs: Long = mCall.timeout().timeoutNanos() / 1000000
urlRequest.start()
if (timeOutMs > 0) {
mResponseCondition.block(timeOutMs)
} else {
@ -32,35 +31,25 @@ class OldCallback(originalRequest: Request, mCall: Call) : AbsCallBack(originalR
if (mException != null) {
throw mException as IOException
}
return this.mResponse
return mResponse
}
override fun onReadCompleted(
request: UrlRequest,
info: UrlResponseInfo,
byteBuffer: ByteBuffer
) {
super.onReadCompleted(request, info, byteBuffer)
if (mException != null) {
mResponseCondition.open()
}
}
override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo) {
super.onSucceeded(request, info)
/**
* 当发生错误时通知子类终止阻塞抛出错误
* @param error
*/
override fun onError(error: IOException) {
mException = error
mResponseCondition.open()
}
override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) {
super.onFailed(request, info, error)
/**
* 请求成功后通知子类结束阻塞返回response
* @param response
*/
override fun onSuccess(response: Response) {
mResponseCondition.open()
}
override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
super.onCanceled(request, info)
mResponseCondition.open()
}
}

@ -12,8 +12,8 @@ val Throwable.msg: String
}
}
fun Throwable.rethrowAsIOException(): IOException {
fun Throwable.asIOException(): IOException {
val newException = IOException(this.message)
newException.initCause(this)
throw newException
return newException
}
Loading…
Cancel
Save