Przeglądaj źródła

fix bugs

1,修复SwitchPreference的异常显示
2,更新一些库
ag2s20150909 4 lat temu
rodzic
commit
20e50b251d

+ 1 - 1
app/src/main/java/io/legado/app/help/http/cronet/AbsCallBack.kt

@@ -148,7 +148,7 @@ abstract class AbsCallBack(
     override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
     override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
         super.onCanceled(request, info)
         super.onCanceled(request, info)
         this.eventListener?.callEnd(mCall)
         this.eventListener?.callEnd(mCall)
-        onError(IOException("Cronet Request Canceled"))
+        //onError(IOException("Cronet Request Canceled"))
     }
     }
 
 
 
 

+ 106 - 0
app/src/main/java/io/legado/app/help/http/cronet/CronetCoroutineInterceptor.kt

@@ -0,0 +1,106 @@
+package io.legado.app.help.http.cronet
+
+import io.legado.app.utils.printOnDebug
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlinx.coroutines.withTimeout
+import okhttp3.*
+import okhttp3.internal.http.receiveHeaders
+import org.chromium.net.UrlRequest
+import org.chromium.net.UrlResponseInfo
+import java.io.IOException
+import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
+
+class CronetCoroutineInterceptor(private val cookieJar: CookieJar = CookieJar.NO_COOKIES) :
+    Interceptor {
+    override fun intercept(chain: Interceptor.Chain): Response {
+        if (chain.call().isCanceled()) {
+            throw IOException("Canceled")
+        }
+        val original: Request = chain.request()
+        //Cronet未初始化
+        return if (!CronetLoader.install() || cronetEngine == null) {
+            chain.proceed(original)
+        } else try {
+            val builder: Request.Builder = original.newBuilder()
+            //移除Keep-Alive,手动设置会导致400 BadRequest
+            builder.removeHeader("Keep-Alive")
+            builder.removeHeader("Accept-Encoding")
+            if (cookieJar != CookieJar.NO_COOKIES) {
+                val cookieStr = getCookie(original.url)
+                //设置Cookie
+                if (cookieStr.length > 3) {
+                    builder.addHeader("Cookie", cookieStr)
+                }
+            }
+
+            val newReq = builder.build()
+            val timeout = chain.call().timeout().timeoutNanos() / 1000000
+            runBlocking() {
+                if (timeout > 0) {
+                    withTimeout(timeout) {
+                        proceedWithCronet(newReq, chain.call()).also { response ->
+                            cookieJar.receiveHeaders(newReq.url, response.headers)
+                        }
+                    }
+                } else {
+                    proceedWithCronet(newReq, chain.call()).also { response ->
+                        cookieJar.receiveHeaders(newReq.url, response.headers)
+                    }
+                }
+            }
+
+        } catch (e: Exception) {
+            //不能抛出错误,抛出错误会导致应用崩溃
+            //遇到Cronet处理有问题时的情况,如证书过期等等,回退到okhttp处理
+            if (!e.message.toString().contains("ERR_CERT_", true)
+                && !e.message.toString().contains("ERR_SSL_", true)
+            ) {
+                e.printOnDebug()
+            }
+            chain.proceed(original)
+        }
+
+    }
+
+
+    private suspend fun proceedWithCronet(request: Request, call: Call): Response =
+        suspendCancellableCoroutine<Response> { coroutine ->
+
+            val callBack = object : AbsCallBack(originalRequest = request, mCall = call) {
+                override fun waitForDone(urlRequest: UrlRequest): Response {
+                    TODO("Not yet implemented")
+                }
+
+                override fun onError(error: IOException) {
+                    coroutine.resumeWithException(error)
+                }
+
+                override fun onSuccess(response: Response) {
+                    coroutine.resume(response)
+                }
+
+                override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
+                    super.onCanceled(request, info)
+                    coroutine.cancel()
+                }
+
+
+            }
+
+            buildRequest(request, callBack)?.start()
+
+
+        }
+
+
+    /** Returns a 'Cookie' HTTP request header with all cookies, like `a=b; c=d`. */
+    private fun getCookie(url: HttpUrl): String = buildString {
+        val cookies = cookieJar.loadForRequest(url)
+        cookies.forEachIndexed { index, cookie ->
+            if (index > 0) append("; ")
+            append(cookie.name).append('=').append(cookie.value)
+        }
+    }
+}

+ 2 - 1
app/src/main/java/io/legado/app/lib/prefs/SwitchPreference.kt

@@ -23,7 +23,7 @@ class SwitchPreference(context: Context, attrs: AttributeSet) :
     }
     }
 
 
     override fun onBindViewHolder(holder: PreferenceViewHolder) {
     override fun onBindViewHolder(holder: PreferenceViewHolder) {
-        super.onBindViewHolder(holder)
+
         val v = Preference.bindView<SwitchCompat>(
         val v = Preference.bindView<SwitchCompat>(
             context,
             context,
             holder,
             holder,
@@ -37,6 +37,7 @@ class SwitchPreference(context: Context, attrs: AttributeSet) :
         if (v is SwitchCompat && !v.isInEditMode) {
         if (v is SwitchCompat && !v.isInEditMode) {
             v.applyTint(context.accentColor)
             v.applyTint(context.accentColor)
         }
         }
+        super.onBindViewHolder(holder)
         onLongClick?.let { listener ->
         onLongClick?.let { listener ->
             holder.itemView.setOnLongClickListener {
             holder.itemView.setOnLongClickListener {
                 listener.invoke(this)
                 listener.invoke(this)

+ 4 - 4
build.gradle

@@ -2,9 +2,9 @@
 
 
 buildscript {
 buildscript {
     ext{
     ext{
-        kotlin_version = '1.7.10'
-        compose_version = '1.2.1'
-        compose_compiler_version = '1.3.0'
+        kotlin_version = '1.7.20'
+        compose_version = '1.3.0-rc01'
+        compose_compiler_version = '1.3.2'
         agp_version = '7.3.1'
         agp_version = '7.3.1'
         exoplayer_version = '2.18.1'
         exoplayer_version = '2.18.1'
         splitties_version = '3.0.0'
         splitties_version = '3.0.0'
@@ -16,7 +16,7 @@ plugins {
     id 'com.android.application' version "$agp_version" apply false
     id 'com.android.application' version "$agp_version" apply false
     id 'com.android.library' version "$agp_version" apply false
     id 'com.android.library' version "$agp_version" apply false
     id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false
     id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false
-    id "de.undercouch.download" version "5.1.0" apply false
+    id "de.undercouch.download" version "5.2.1" apply false
     id "com.google.gms.google-services" version "4.3.10" apply false
     id "com.google.gms.google-services" version "4.3.10" apply false
 }
 }