gpt4 book ai didi

android - 为什么 Kotlin 中某些 GlobalScope.launch 调用的内容静默执行失败?

转载 作者:行者123 更新时间:2023-11-29 23:18:56 26 4
gpt4 key购买 nike

我是 Kotlin 的新手 - 事实上我从来没有计划使用它,但我正在尝试使用 CameraKit库,它使用似乎是为其 API 接口(interface)生成的 Kotlin 层。我一直遇到相机未正确断开连接的问题,有问题的代码(或者至少在我看来是最相关的部分)如下所示:

class CameraPreview : FrameLayout, CameraEvents {
var TAG = "CameraPreview.kt"
var lifecycleState: LifecycleState = LifecycleState.STOPPED
var surfaceState: SurfaceState = SurfaceState.SURFACE_WAITING
var cameraState: CameraState = CameraState.CAMERA_CLOSED
set(state) {
field = state
when (state) {
CameraState.CAMERA_OPENED -> {
listener?.onCameraOpened()
}
CameraState.PREVIEW_STARTED -> {
listener?.onPreviewStarted()
}
CameraState.PREVIEW_STOPPED -> {
listener?.onPreviewStopped()
}
CameraState.CAMERA_CLOSING -> {
listener?.onCameraClosed()
}
else -> {
// ignore
}
}
}


private val cameraDispatcher: CoroutineDispatcher = newSingleThreadContext("CAMERA")
private var cameraOpenContinuation: Continuation<Unit>? = null
private var previewStartContinuation: Continuation<Unit>? = null


init {
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
displayOrientation = windowManager.defaultDisplay.rotation * 90

cameraSurfaceView.cameraSurfaceTextureListener = object : CameraSurfaceTextureListener {
override fun onSurfaceReady(cameraSurfaceTexture: CameraSurfaceTexture) {
surfaceTexture = cameraSurfaceTexture
surfaceState = SurfaceState.SURFACE_AVAILABLE
if (lifecycleState == LifecycleState.STARTED || lifecycleState == LifecycleState.RESUMED) {
resume()
}
}
}

addView(cameraSurfaceView)
}

fun start(facing: CameraFacing) {
GlobalScope.launch(cameraDispatcher) {
runBlocking {
Log.i(TAG, "Start preview state is "+lifecycleState)
lifecycleState = LifecycleState.STARTED
cameraFacing = facing
openCamera()
}
}
}

fun resume() {
GlobalScope.launch(cameraDispatcher) {
runBlocking {
Log.i("CameraPreview.kt", "Resume preview state is "+lifecycleState)
lifecycleState = LifecycleState.RESUMED
try {
startPreview()
} catch (e: Exception) {
Log.i("CameraPreview.kt", "Start preview hit an exception: "+e.message)
// camera or surface not ready, wait.
}
}
}
}

fun pause() {
Log.i("CameraPreview.kt", "Pause called");
GlobalScope.launch(cameraDispatcher) {
Log.i(TAG, "Pause scope launched, runblocking call ahead.")
runBlocking {
Log.i("CameraPreview.kt", "Pause initiated, stop preview state is "+lifecycleState)
lifecycleState = LifecycleState.PAUSED
stopPreview()
}
}

}

fun stop() {
Log.i("CameraPreview.kt", "Stop called");
GlobalScope.launch(cameraDispatcher) {
Log.i(TAG, "Stop scope launched, runblocking call ahead.")
runBlocking {
Log.i("CameraPreview.kt", "Stop initiated, close camera state is "+lifecycleState)
lifecycleState = LifecycleState.STOPPED
closeCamera()
}

}

}



enum class CameraState {
CAMERA_OPENING,
CAMERA_OPENED,
PREVIEW_STARTING,
PREVIEW_STARTED,
PREVIEW_STOPPING,
PREVIEW_STOPPED,
CAMERA_CLOSING,
CAMERA_CLOSED;
}

// Camera control:

private suspend fun openCamera(): Unit = suspendCoroutine {
cameraOpenContinuation = it
cameraState = CameraState.CAMERA_OPENING
Log.i("CameraPreview.kt", "openCamera call state is "+lifecycleState)
cameraApi.open(cameraFacing)
}

private suspend fun startPreview(): Unit = suspendCoroutine {
Log.i("CameraPreview.kt", "startPreview, lifecyclestate "+ lifecycleState);
// do stuff

}

private suspend fun stopPreview(): Unit = suspendCoroutine {
Log.i("CameraPreview.kt", "Stop preview state is "+lifecycleState)
cameraState = CameraState.PREVIEW_STOPPING
cameraApi.stopPreview()
it.resume(Unit)
}

private suspend fun closeCamera(): Unit = suspendCoroutine {
Log.i("CameraPreview.kt", "Close camera state is "+lifecycleState)
cameraState = CameraState.CAMERA_CLOSING
cameraApi.release()
it.resume(Unit)
}


}

现在,当 startresume 被调用时,它们会执行它们应该执行的操作。当调用 pausestop 时,没有明显的变化,相机预览既没有暂停也没有停止。

我的日志记录表明,当 pause() 被调用时,会记录初始调用,但 GlobalScope.launch(cameraDispatcher) 中的日志语句从未出现。似乎 GlobalScope 只是将协程启动到空白中。当 startresume 正常工作时,调用或调度程序似乎没有问题,但很难知道还能在哪里查看

如果我将 pausestop 协同例程的内容放在 GlobalScope.launch 之外来创建这样的东西:

fun pause() {
Log.i("CameraPreview.kt", "Pause called");
GlobalScope.launch(cameraDispatcher) {
Log.i(TAG, "Pause scope launched, runblocking call ahead.")
runBlocking {
Log.i("CameraPreview.kt", "Pause initiated, stop preview state is "+lifecycleState)
lifecycleState = LifecycleState.PAUSED
stopPreview()
}
}
cameraState = CameraState.PREVIEW_STOPPING
cameraApi.stopPreview()
}

它现在不仅可以工作,而且协程也开始处理后续调用,就好像被调用的内容不知何故被卡住了。运行时,我在 Logcat 中看不到任何错误消息。

这是我第一次接触 Kotlin,所以我不完全确定它应该如何工作,但似乎完全绕过基本代码可能不是规范的一部分。谁能建议这里发生了什么,或者我如何才能找到问题的真正根源?

最佳答案

问题可能是您正在使用一个共享的单线程调度程序 cameraDispatcher然后您可以使用 runBlocking 阻止它.我不确定这段代码是基于什么,但是 runBlocking在其文档中有一个警告,它应该只在协程和严格线程绑定(bind)执行之间桥接时使用,如 main或测试框架。

如果您删除对 runBlocking 的所有调用,您的代码应该仍然有效

关于android - 为什么 Kotlin 中某些 GlobalScope.launch 调用的内容静默执行失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54790540/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com