Переключение на подпрограмму «Main» и приостановка ее для отправки результата обратно в сопрограмму «IO» - PullRequest
1 голос
/ 05 февраля 2020

Когда выполняется длинная сопрограмма 'IO', мне нужно получить доступ к представлению, чтобы в какой-то момент времени нарисовать его содержимое на холсте. Я предполагаю, что мне нужно переключиться на «Main» сопрограмму, прежде чем делать что-либо о представлении И я также предполагаю, что мне нужно подождать, пока представление сможет выполнить свою задачу. Я делаю это так:

suspend fun tryBlindFrameBitmap(
    frame: View
) = withContext(Dispatchers.IO) {

    // offscreen work

    createBitmapFromView(frame, calculatedWidth, calculatedHeight)?.let {
        // some bitmap exploration
        bitmap.recycle()
    }

    // offscreen work
}

suspend fun createBitmapFromView(
    view: View,
    width: Int,
    height: Int
): Bitmap? {

    val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    bitmap.setHasAlpha(true)
    val canvas = Canvas(bitmap)

    return withContext(Dispatchers.Main) {

        suspendCoroutine<Bitmap> { continuation ->

            view.post {
                view.draw(canvas)
                continuation.resume(bitmap)
            }
        }
    }
}

Я чувствую, что делаю что-то не так или по «лучшему» пути. Я еще не тестировал свой код, будет ли это работать?

Как мне улучшить ситуацию?

1 Ответ

1 голос
/ 05 февраля 2020

suspendCoroutine<Bitmap> является избыточным, withContext(Main) уже опубликовал ваш код в ветке GUI. Также кажется, что тип возвращаемого значения излишне обнуляем. Вы можете написать свою функцию так:

suspend fun createBitmapFromView(view: View, width: Int, height: Int): Bitmap {
    val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
            .apply { setHasAlpha(true) }
    withContext(Dispatchers.Main) {
        view.draw(Canvas(bitmap))
    }
    return bitmap
}
...