繁体   English   中英

如何在 Jetpack Compose 中关闭主线程?

[英]How to do work off the main thread in Jetpack Compose?

在 Jetpack Compose 应用程序中,我有一个 LazyVerticalGrid 缩略图,每个缩略图都需要在撰写时绘制在位图支持的 Canvas 中。

如果我只是在 Canvas 的 DrawScope 中绘制缩略图,则可以正确绘制缩略图,但用户体验很差。 当用户滚动 LazyVerticalGrid 时,每个缩略图都会自行绘制,因此会出现很多卡顿现象。

我原以为 Jetpack Compose 在需要时在后台线程中组合,但这一切似乎都发生在主线程上,导致严重的卡顿,即使在最新的手机上也是如此。

我可以通过使用 LaunchedEffect withContext(IO) 在另一个线程上绘制到 Canvas 的底层位图来解决卡顿问题。 但问题是,Compose 不知道在绘制位图时重新组合 Canvas,所以我经常以半绘制的缩略图结束。

有没有一种方法可以在主线程之外完成工作,然后在完成工作后重新组合?

这是卡住的代码(为简洁起见进行了编辑),然后是在绘图完成后并不总是重新组合的非卡住版本:

   val imageBitmap = remember {Bitmap.createBitmap(515, 618, Bitmap.Config.ARGB_8888)}
   val bitmapCanvas = remember { android.graphics.Canvas(imageBitmap) }
   ElevatedCard() {
      Canvas() {
         bitmapCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
         penStrokes.forEach {
           inker.drawEvent(it)
         }
         this.drawImage(imageBitmap.asImageBitmap())
       }
   }

非简陋但仍然不正确

   val imageBitmap = remember {Bitmap.createBitmap(515, 618, Bitmap.Config.ARGB_8888)}
   val bitmapCanvas = remember { android.graphics.Canvas(imageBitmap) }
   LaunchedEffect(Unit) {
      withContext(IO) {
         bitmapCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
         penStrokes.forEach {
           inker.drawEvent(it)
         }
      }
   }
   ElevatedCard() {
      Canvas() {
         this.drawImage(imageBitmap.asImageBitmap())
       }
   }

最后,我使用了人们似乎用来强制 Jetpack Compose 根据命令重绘的常见“invalidate++”kludge。 我认为它有一点代码味道,但它确实有效。

val imageBitmap = remember {Bitmap.createBitmap(515, 618, 
     Bitmap.Config.ARGB_8888)}
val bitmapCanvas = remember { android.graphics.Canvas(imageBitmap) }
var invalidate by remember { mutableStateOf(0) }


LaunchedEffect(Unit) {
  withContext(IO) {
     bitmapCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
     penStrokes.forEach {
       inker.drawEvent(it)
     }
     invalidate++
  }
}

ElevatedCard() {
   Canvas() {
      invalidate.let {
           this.drawImage(imageBitmap.asImageBitmap())
      }
   }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM