Horis 2 лет назад
Родитель
Сommit
3c38776cee

+ 2 - 2
app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt

@@ -11,8 +11,8 @@ import androidx.recyclerview.widget.RecyclerView
 import androidx.viewbinding.ViewBinding
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.utils.buildMainHandler
+import io.legado.app.utils.withTimeoutOrNullAsync
 import kotlinx.coroutines.ensureActive
-import kotlinx.coroutines.withTimeoutOrNull
 import splitties.views.onLongClick
 import java.util.Collections
 
@@ -152,7 +152,7 @@ abstract class RecyclerAdapter<ITEM, VB : ViewBinding>(protected val context: Co
             }
             diffJob?.cancel()
             diffJob = Coroutine.async {
-                val diffResult = if (skipDiff) withTimeoutOrNull(500L) {
+                val diffResult = if (skipDiff) withTimeoutOrNullAsync(500L) {
                     DiffUtil.calculateDiff(callback)
                 } else {
                     DiffUtil.calculateDiff(callback)

+ 37 - 0
app/src/main/java/io/legado/app/utils/CoroutineExtensions.kt

@@ -0,0 +1,37 @@
+package io.legado.app.utils
+
+import io.legado.app.help.coroutine.Coroutine
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
+
+class TimeoutCancellationException(msg: String) : CancellationException(msg)
+
+suspend fun <T> withTimeoutAsync(delayMillis: Long, block: suspend CoroutineScope.() -> T): T {
+    return suspendCancellableCoroutine { cout ->
+        Coroutine.async(context = cout.context) {
+            launch {
+                delay(delayMillis)
+                if (!cout.isCompleted) {
+                    cout.resumeWithException(TimeoutCancellationException("Timed out waiting for $delayMillis ms"))
+                }
+            }
+            val result = block()
+            if (!cout.isCompleted) {
+                cout.resume(result)
+            }
+        }
+    }
+}
+
+suspend fun <T> withTimeoutOrNullAsync(delayMillis: Long, block: suspend CoroutineScope.() -> T): T? {
+    return try {
+        withTimeoutAsync(delayMillis, block)
+    } catch (e: TimeoutCancellationException) {
+        null
+    }
+}