diff --git a/app/cronetlib/cronet_api.jar b/app/cronetlib/cronet_api.jar index 9a9cb0849..07788bf33 100644 Binary files a/app/cronetlib/cronet_api.jar and b/app/cronetlib/cronet_api.jar differ diff --git a/app/cronetlib/cronet_impl_common_java.jar b/app/cronetlib/cronet_impl_common_java.jar index 5dd2cb1d0..9239b90fc 100644 Binary files a/app/cronetlib/cronet_impl_common_java.jar and b/app/cronetlib/cronet_impl_common_java.jar differ diff --git a/app/src/main/assets/cronet.json b/app/src/main/assets/cronet.json index 97a9e03a2..095a97d61 100644 --- a/app/src/main/assets/cronet.json +++ b/app/src/main/assets/cronet.json @@ -1 +1 @@ -{"arm64-v8a":"18441011d4a2e3751b8152ad05ab24da","armeabi-v7a":"701930e54c2cfa3d6d0df37168ecc4a6","x86":"3d4ebb7f23b910a8b50a2966eb39bbe7","x86_64":"9be68a8e03867c8f844e8eec88fe09ed","version":"93.0.4577.62"} \ No newline at end of file +{"arm64-v8a":"9717593e18b283ac23a0be548c5aeea6","armeabi-v7a":"44c83d10c4a32ff20466bd7ef363c264","x86":"ce4ad637ead52aa3761e4ce3083f6453","x86_64":"a9924d9d2a31510d7335f6c6af32abc0","version":"93.0.4577.82"} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index 58e880e48..63113a251 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -29,6 +29,7 @@ val okHttpClient: OkHttpClient by lazy { .connectTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS) + .callTimeout(60,TimeUnit.SECONDS) .sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager) .retryOnConnectionFailure(true) .hostnameVerifier(SSLHelper.unsafeHostnameVerifier) diff --git a/app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt b/app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt index ab4353049..2886b8db1 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt @@ -12,11 +12,11 @@ import org.chromium.net.ExperimentalCronetEngine import org.chromium.net.UploadDataProviders import org.chromium.net.UrlRequest import splitties.init.appCtx -import java.util.concurrent.Executor +import java.util.concurrent.ExecutorService import java.util.concurrent.Executors -val executor: Executor by lazy { Executors.newCachedThreadPool() } +val executor: ExecutorService by lazy { Executors.newCachedThreadPool() } val cronetEngine: ExperimentalCronetEngine by lazy { if (AppConfig.isGooglePlay) { @@ -27,16 +27,17 @@ val cronetEngine: ExperimentalCronetEngine by lazy { val builder = ExperimentalCronetEngine.Builder(appCtx).apply { - if (!AppConfig.isGooglePlay&&CronetLoader.install()) { + if (!AppConfig.isGooglePlay && CronetLoader.install()) { setLibraryLoader(CronetLoader)//设置自定义so库加载 } setStoragePath(appCtx.externalCacheDir?.absolutePath)//设置缓存路径 - enableHttpCache(HTTP_CACHE_DISK, (1024 * 1024 * 50).toLong())//设置缓存模式 + enableHttpCache(HTTP_CACHE_DISK, (1024 * 1024 * 50).toLong())//设置50M的磁盘缓存 enableQuic(true)//设置支持http/3 enableHttp2(true) //设置支持http/2 enablePublicKeyPinningBypassForLocalTrustAnchors(true) enableBrotli(true)//Brotli压缩 + } val engine = builder.build() Log.d("Cronet", "Cronet Version:" + engine.versionString) @@ -49,31 +50,32 @@ val cronetEngine: ExperimentalCronetEngine by lazy { fun buildRequest(request: Request, callback: UrlRequest.Callback): UrlRequest { val url = request.url.toString() - val requestBuilder = cronetEngine.newUrlRequestBuilder(url, callback, executor) - requestBuilder.setHttpMethod(request.method) - val headers: Headers = request.headers - headers.forEachIndexed { index, _ -> - requestBuilder.addHeader(headers.name(index), headers.value(index)) - } - val requestBody = request.body - if (requestBody != null) { - val contentType: MediaType? = requestBody.contentType() - if (contentType != null) { - requestBuilder.addHeader("Content-Type", contentType.toString()) - } else { - requestBuilder.addHeader("Content-Type", "text/plain") + return cronetEngine.newUrlRequestBuilder(url, callback, executor).apply { + setHttpMethod(request.method)//设置 + allowDirectExecutor() + headers.forEachIndexed { index, _ -> + addHeader(headers.name(index), headers.value(index)) } - val buffer = Buffer() - requestBody.writeTo(buffer) - requestBuilder.setUploadDataProvider( - UploadDataProviders.create(buffer.readByteArray()), - executor - ) + if (requestBody != null) { + val contentType: MediaType? = requestBody.contentType() + if (contentType != null) { + addHeader("Content-Type", contentType.toString()) + } else { + addHeader("Content-Type", "text/plain") + } + val buffer = Buffer() + requestBody.writeTo(buffer) + setUploadDataProvider( + UploadDataProviders.create(buffer.readByteArray()), + executor + ) + + } + + }.build() - } - return requestBuilder.build() } diff --git a/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt b/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt index c51c76ee5..ae9f85fe4 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt @@ -42,7 +42,7 @@ class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor { @Throws(IOException::class) private fun proceedWithCronet(request: Request, call: Call): Response { - val callback = CronetUrlRequestCallback(request, call) + val callback = CronetRequestCallback(request, call) val urlRequest = buildRequest(request, callback) urlRequest.start() return callback.waitForDone(urlRequest) @@ -50,7 +50,7 @@ class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor { private fun getCookie(url: HttpUrl): String { val sb = StringBuilder() - //处理从 Cookjar 获取到的Cookies + //处理从 Cookiejar 获取到的Cookies if (cookieJar != null) { val cookies = cookieJar.loadForRequest(url) for (cookie in cookies) { diff --git a/app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt b/app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt index 496774b50..9682bb017 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt @@ -24,8 +24,8 @@ import java.util.* object CronetLoader : CronetEngine.Builder.LibraryLoader() { //https://storage.googleapis.com/chromium-cronet/android/92.0.4515.159/Release/cronet/libs/arm64-v8a/libcronet.92.0.4515.159.so - //https://cdn.jsdelivr.net/gh/ag2s20150909/cronet-repo@92.0.4515.159/cronet/92.0.4515.127/arm64-v8a/libcronet.92.0.4515.159.so.js private const val TAG = "CronetLoader" + private const val soVersion = BuildConfig.Cronet_Version private const val soName = "libcronet.$soVersion.so" private val soUrl: String @@ -34,6 +34,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() { private var cpuAbi: String? = null private var md5: String var download = false + private var cacheInstall = false init { soUrl = ("https://storage.googleapis.com/chromium-cronet/android/" @@ -49,18 +50,33 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() { Log.e(TAG, "soUrl:$soUrl") } + + /** + * 判断Cronet是否安装完成 + * @return + */ + fun install(): Boolean { + if (cacheInstall) { + return true + } if (AppConfig.isGooglePlay) { //检查GMS的Cronet服务是否安装 - return CronetProviderInstaller.isInstalled() + cacheInstall = CronetProviderInstaller.isInstalled() + return cacheInstall } if (md5.length != 32 || !soFile.exists() || md5 != getFileMD5(soFile)) { - return false + cacheInstall = false + return cacheInstall } - return soFile.exists() + cacheInstall = soFile.exists() + return cacheInstall } + /** + * 预加载Cronet + */ fun preDownload() { if (AppConfig.isGooglePlay) { CronetProviderInstaller.installProvider(appCtx) @@ -269,6 +285,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() { Log.e(TAG, "download success, copy to $destSuccessFile") //下载成功拷贝文件 copyFile(downloadTempFile, destSuccessFile) + cacheInstall=false val parentFile = downloadTempFile.parentFile @Suppress("SameParameterValue") deleteHistoryFile(parentFile!!, null) diff --git a/app/src/main/java/io/legado/app/help/http/cronet/CronetUrlRequestCallback.kt b/app/src/main/java/io/legado/app/help/http/cronet/CronetRequestCallback.kt similarity index 91% rename from app/src/main/java/io/legado/app/help/http/cronet/CronetUrlRequestCallback.kt rename to app/src/main/java/io/legado/app/help/http/cronet/CronetRequestCallback.kt index c00ec2de3..ea59541eb 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/CronetUrlRequestCallback.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/CronetRequestCallback.kt @@ -15,7 +15,7 @@ import java.io.IOException import java.nio.ByteBuffer import java.util.* -class CronetUrlRequestCallback @JvmOverloads internal constructor( +class CronetRequestCallback @JvmOverloads internal constructor( private val originalRequest: Request, private val mCall: Call, eventListener: EventListener? = null, @@ -100,6 +100,8 @@ class CronetUrlRequestCallback @JvmOverloads internal constructor( info: UrlResponseInfo, byteBuffer: ByteBuffer ) { + + byteBuffer.flip() try { @@ -143,9 +145,8 @@ class CronetUrlRequestCallback @JvmOverloads internal constructor( responseCallback?.onFailure(mCall, e) } - override fun onCanceled(request: UrlRequest, info: UrlResponseInfo) { + override fun onCanceled(request: UrlRequest, info: UrlResponseInfo?) { mResponseCondition.open() - this.eventListener?.callEnd(mCall) @@ -184,20 +185,23 @@ class CronetUrlRequestCallback @JvmOverloads internal constructor( private fun headersFromResponse(responseInfo: UrlResponseInfo): Headers { val headers = responseInfo.allHeadersAsList - val headerBuilder = Headers.Builder() - for ((key, value) in headers) { - try { - if (key.equals("content-encoding", ignoreCase = true)) { - // Strip all content encoding headers as decoding is done handled by cronet - continue + return Headers.Builder().apply { + for ((key, value) in headers) { + try { + + if (key.equals("content-encoding", ignoreCase = true)) { + // Strip all content encoding headers as decoding is done handled by cronet + continue + } + add(key, value) + } catch (e: Exception) { + Log.w(TAG, "Invalid HTTP header/value: $key$value") + // Ignore that header } - headerBuilder.add(key, value) - } catch (e: Exception) { - Log.w(TAG, "Invalid HTTP header/value: $key$value") - // Ignore that header } - } - return headerBuilder.build() + + }.build() + } private fun responseFromResponse( diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt index a785c05b2..8f84822bd 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt @@ -118,6 +118,8 @@ class ReadAloudDialog : BaseDialogFragment() { seekTtsSpeechRate.isEnabled = !isChecked upTtsSpeechRate() } + //设置保存的默认值 + seekTtsSpeechRate.progress=AppConfig.ttsSpeechRate seekTtsSpeechRate.setOnSeekBarChangeListener(object : SeekBarChangeListener { override fun onStopTrackingTouch(seekBar: SeekBar) { AppConfig.ttsSpeechRate = seekBar.progress diff --git a/gradle.properties b/gradle.properties index dea2f01e9..fe3fbf2f6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,4 +22,4 @@ kotlin.code.style=official android.enableResourceOptimizations=true -CronetVersion=93.0.4577.62 +CronetVersion=93.0.4577.82