mirror of
https://mirror.skon.top/github.com/gkd-kit/gkd
synced 2026-04-20 21:00:12 +08:00
perf: use suspendCancellableCoroutine
This commit is contained in:
@@ -14,6 +14,7 @@ import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runInterruptible
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import li.songe.gkd.META
|
||||
@@ -42,7 +43,6 @@ import li.songe.selector.Selector
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
|
||||
private val eventDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
@@ -200,15 +200,21 @@ class A11yRuleEngine(val service: A11yCommonImpl) {
|
||||
}
|
||||
|
||||
// 某些场景耗时 5000 ms
|
||||
private suspend fun getTimeoutActiveWindow(): AccessibilityNodeInfo? = suspendCoroutine { s ->
|
||||
val temp = atomic<Continuation<AccessibilityNodeInfo?>?>(s)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
delay(500L)
|
||||
temp.getAndUpdate { null }?.resume(null)
|
||||
}
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val a = safeActiveWindow
|
||||
temp.getAndUpdate { null }?.resume(a)
|
||||
private suspend fun getTimeoutActiveWindow(): AccessibilityNodeInfo? {
|
||||
return suspendCancellableCoroutine { s ->
|
||||
val temp = atomic<Continuation<AccessibilityNodeInfo?>?>(s)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
delay(500L)
|
||||
if (s.isActive) {
|
||||
temp.getAndUpdate { null }?.resume(null)
|
||||
}
|
||||
}
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val a = safeActiveWindow
|
||||
if (s.isActive) {
|
||||
temp.getAndUpdate { null }?.resume(a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.view.accessibility.AccessibilityNodeInfo
|
||||
import android.view.accessibility.AccessibilityWindowInfo
|
||||
import com.google.android.accessibility.selecttospeak.SelectToSpeakService
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import li.songe.gkd.a11y.A11yCommonImpl
|
||||
import li.songe.gkd.a11y.A11yRuleEngine
|
||||
import li.songe.gkd.a11y.topActivityFlow
|
||||
@@ -28,7 +29,6 @@ import li.songe.gkd.util.componentName
|
||||
import li.songe.gkd.util.runMainPost
|
||||
import li.songe.gkd.util.toast
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
@SuppressLint("AccessibilityPolicy")
|
||||
open class A11yService : AccessibilityService(), OnA11yLife, A11yCommonImpl {
|
||||
@@ -36,26 +36,35 @@ open class A11yService : AccessibilityService(), OnA11yLife, A11yCommonImpl {
|
||||
override val scope = useScope()
|
||||
override val windowNodeInfo: AccessibilityNodeInfo? get() = rootInActiveWindow
|
||||
override val windowInfos: List<AccessibilityWindowInfo> get() = windows
|
||||
override suspend fun screenshot(): Bitmap? = suspendCoroutine { continuation ->
|
||||
override suspend fun screenshot(): Bitmap? = suspendCancellableCoroutine { cont ->
|
||||
if (AndroidTarget.R) {
|
||||
takeScreenshot(
|
||||
Display.DEFAULT_DISPLAY,
|
||||
application.mainExecutor,
|
||||
object : TakeScreenshotCallback {
|
||||
override fun onFailure(errorCode: Int) = continuation.resume(null)
|
||||
override fun onSuccess(screenshot: ScreenshotResult) = try {
|
||||
continuation.resume(
|
||||
Bitmap.wrapHardwareBuffer(
|
||||
screenshot.hardwareBuffer, screenshot.colorSpace
|
||||
)
|
||||
)
|
||||
} finally {
|
||||
screenshot.hardwareBuffer.close()
|
||||
override fun onFailure(errorCode: Int) {
|
||||
if (cont.isActive) {
|
||||
cont.resume(null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSuccess(screenshot: ScreenshotResult) {
|
||||
try {
|
||||
if (cont.isActive) {
|
||||
cont.resume(
|
||||
Bitmap.wrapHardwareBuffer(
|
||||
screenshot.hardwareBuffer, screenshot.colorSpace
|
||||
)
|
||||
)
|
||||
}
|
||||
} finally {
|
||||
screenshot.hardwareBuffer.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
continuation.resume(null)
|
||||
cont.resume(null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import li.songe.gkd.util.stopCoroutine
|
||||
import li.songe.gkd.util.throttle
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
data class AlertDialogOptions(
|
||||
val title: @Composable (() -> Unit)? = null,
|
||||
@@ -111,9 +111,11 @@ suspend fun MutableStateFlow<AlertDialogOptions?>.getResult(
|
||||
dismissText: String = DEFAULT_DISMISS_TEXT,
|
||||
error: Boolean = false,
|
||||
): Boolean {
|
||||
return suspendCoroutine { s ->
|
||||
return suspendCancellableCoroutine { s ->
|
||||
val dismiss = {
|
||||
s.resume(false)
|
||||
if (s.isActive) {
|
||||
s.resume(false)
|
||||
}
|
||||
this.value = null
|
||||
}
|
||||
updateDialogOptions(
|
||||
@@ -123,7 +125,9 @@ suspend fun MutableStateFlow<AlertDialogOptions?>.getResult(
|
||||
onDismissRequest = if (dismissRequest) dismiss else ({}),
|
||||
confirmText = confirmText,
|
||||
confirmAction = {
|
||||
s.resume(true)
|
||||
if (s.isActive) {
|
||||
s.resume(true)
|
||||
}
|
||||
this.value = null
|
||||
},
|
||||
dismissText = dismissText,
|
||||
|
||||
@@ -14,29 +14,31 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import kotlinx.coroutines.CancellableContinuation
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import li.songe.gkd.ui.WebViewRoute
|
||||
import li.songe.gkd.ui.share.LocalMainViewModel
|
||||
import li.songe.gkd.util.ShortUrlSet
|
||||
import li.songe.gkd.util.subsItemsFlow
|
||||
import li.songe.gkd.util.throttle
|
||||
import li.songe.gkd.util.toast
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
|
||||
class InputSubsLinkOption {
|
||||
private val showFlow = MutableStateFlow(false)
|
||||
private val valueFlow = MutableStateFlow("")
|
||||
private val initValueFlow = MutableStateFlow("")
|
||||
private var continuation: Continuation<String?>? = null
|
||||
private var continuation: CancellableContinuation<String?>? = null
|
||||
|
||||
private fun resume(value: String?) {
|
||||
showFlow.value = false
|
||||
valueFlow.value = ""
|
||||
initValueFlow.value = ""
|
||||
continuation?.resume(value)
|
||||
if (continuation?.isActive == true) {
|
||||
continuation?.resume(value)
|
||||
}
|
||||
continuation = null
|
||||
}
|
||||
|
||||
@@ -65,7 +67,7 @@ class InputSubsLinkOption {
|
||||
initValueFlow.value = initValue
|
||||
valueFlow.value = initValue
|
||||
showFlow.value = true
|
||||
return suspendCoroutine {
|
||||
return suspendCancellableCoroutine {
|
||||
continuation = it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ import android.media.projection.MediaProjectionManager
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.core.graphics.createBitmap
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
// https://github.com/npes87184/ScreenShareTile/blob/master/app/src/main/java/com/npes87184/screenshottile/ScreenshotService.kt
|
||||
|
||||
@@ -53,7 +53,7 @@ class ScreenshotUtil(
|
||||
}
|
||||
|
||||
// TODO android13 上一半概率获取到全透明图片, android12 暂无此问题
|
||||
suspend fun execute() = suspendCoroutine { block ->
|
||||
suspend fun execute() = suspendCancellableCoroutine { cont ->
|
||||
imageReader = ImageReader.newInstance(
|
||||
width, height,
|
||||
PixelFormat.RGBA_8888, 2
|
||||
@@ -92,14 +92,18 @@ class ScreenshotUtil(
|
||||
bitmap = Bitmap.createBitmap(bitmapWithStride, 0, 0, width, height)
|
||||
if (!bitmap.isFullTransparent()) {
|
||||
imageReader?.setOnImageAvailableListener(null, null)
|
||||
block.resume(bitmap)
|
||||
if (cont.isActive) {
|
||||
cont.resume(bitmap)
|
||||
}
|
||||
resumed = true
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
imageReader?.setOnImageAvailableListener(null, null)
|
||||
block.resumeWithException(e)
|
||||
if (cont.isActive) {
|
||||
cont.resumeWithException(e)
|
||||
}
|
||||
} finally {
|
||||
bitmapWithStride?.recycle()
|
||||
image?.close()
|
||||
|
||||
Reference in New Issue
Block a user