如何在 Jetpack Compose 中实现突发模式

问题描述 投票:0回答:1

我正在尝试在 jetpack compose 中实现突发模式,但我无法做到。 代码如下:

跨多个 Stack Overflow 线程进行搜索没有找到与此问题相关的解决方案或文档。 MAX_BURST_PHOTOS:定义可以拍摄的连拍照片的最大数量。

photosTaken:跟踪拍摄的照片数量。

isBurstMode:布尔变量,指示是否启用突发模式。

LaunchedEffect:当isBurstMode改变时启动协程,在isBurstMode为true且拍摄张数小于MAX_BURST_PHOTOS时连续拍摄连拍照片。

takeBurstPhotos:连拍照片的函数,每拍一张照片都会触发 viewModel.onTakePhoto(bitmap)

增加每张照片拍摄后拍摄的照片,并在照片之间引入 300 毫秒的延迟。

当连拍照片数量达到最大时,导航至“MomentVideoPreview”。

代表可点击 UI 元素的可组合框。

clickable 修饰符在单击 Box 时切换 isBurstMode 变量。

Box 的大小取决于窗口的大小。 val MAX_BURST_PHOTOS 通过记住 { mutableStateOf(30) } var photostaken by Remember { mutableStateOf(0) }

var isBurstMode by remember { mutableStateOf(false) }

LaunchedEffect(isBurstMode) {
    coroutineScope.launch {
        while (isBurstMode && photosTaken < MAX_BURST_PHOTOS) {
            takeBurstPhotos(
                controller = controller,
                onPhotoTaken = { bitmap ->
                    viewModel.onTakePhoto(bitmap)
                  
                },
                context = context
            )
            photosTaken++
            delay(300)
        }
        if (photosTaken == MAX_BURST_PHOTOS) {
            onNavigate.navigate("MomentVideoPreview")
        }
    }
}

Box(
    Modifier
          .clip(CircleShape)
          .background(
                Color.Transparent
          )
          .border(13.dp, Color.White, CircleShape)
          .size(if (rememberWindowSize().widthSize == 360.dp) 70.dp else 75.dp)
          .clickable {
              isBurstMode = !isBurstMode
           }

    )

可以解决这个错误吗?

kotlin error-handling android-jetpack-compose android-camera
1个回答
0
投票

堆栈跟踪表明您正在尝试从非主线程的线程中拍照。

java.lang.IllegalStateException:不在应用程序的主线程中

我怀疑这个问题发生在你的

takeBurstPhotos
函数中。一种可能的解决方案是显式定义与相机相关的代码段应运行的线程。我们可以通过使用
withContext
块来做到这一点,如下所示:

LaunchedEffect(isBurstMode) {
    coroutineScope.launch {
        while (isBurstMode && photosTaken < MAX_BURST_PHOTOS) {
            withContext(Dispatchers.Main) {  // execute this code on main thread
                takeBurstPhotos(
                    controller = controller,
                    onPhotoTaken = { bitmap ->
                        viewModel.onTakePhoto(bitmap)
                  
                    },
                    context = context
                )
            }
            photosTaken++
            delay(300)
        }
        if (photosTaken == MAX_BURST_PHOTOS) {
            onNavigate.navigate("MomentVideoPreview")
        }
    }
}

根据

此 GitHub 问题
,带有 Camera is closed 的堆栈跟踪可能有多种原因:

  • 您正在模拟器上运行该应用程序。
    您可以尝试通过将模拟器相机设置从
    VirtualScene
    更改为
    Emulated
    来修复该问题。
  • 保存图像后,您忘记在
    image.close()
    函数中调用
    override fun onCaptureSuccess(image: ImageProxy)
    。如果不这样做并拍摄大量图像,可能会导致资源泄漏。
  • 当图像仍在保存时,您将应用程序发送到后台。
    在这种情况下,请使用 try catch 块来捕获异常。

除此之外,如果没有更多代码,很难调查原因。

© www.soinside.com 2019 - 2024. All rights reserved.