Почему lifecycleScope.launch во фрагменте блокирует UI-поток?

Это блокирует поток пользовательского интерфейса, но если я использую GlobalScope, пользовательский интерфейс не будет заблокирован.

lifecycleScope.launch {

            activity?.runOnUiThread {
                Toast.makeText(activity, getString(R.string.txt_savinginprogress), Toast.LENGTH_SHORT).show()
            }

            val fileName = "Picture" + System.currentTimeMillis().toString()
            val folderName = "BucketList"

            val bitmap: Bitmap? = photoURI?.let { it1 -> getBitmapFromUri(it1) }

            activity?.let {
                bitmap?.let { it1 ->
                    PhotoSaveHelper(it).savePhoto(fileName, folderName, it1)
                }
            }

            activity?.runOnUiThread {
                Toast.makeText(activity, getString(R.string.txt_saved), Toast.LENGTH_SHORT).show()
            }
        }
    }

Lifecyclescope по умолчанию использует диспетчер основного потока.

Tenfour04 09.12.2020 21:41

Спасибо, моя проблема решена: lifecycleScope.launch { withContext(Dispatchers.IO) { ... }}

Botond Sulyok 09.12.2020 21:47

Да, это способ правильно использовать его. И вообще не нужно runOnUiThread. Просто держите эти части кода вне блоков withContext.

Tenfour04 09.12.2020 21:48
8
3
3 674
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

lifecycleScope.launch{} по умолчанию выполняет код внутри потока main. Попробуйте использовать приведенный ниже код для запуска сопрограммы в диспетчере ввода-вывода (для длительных и ресурсоемких задач).

lifecycleScope.launch(Dispatchers.IO) {
       withContext(Dispatchers.Main) {
            Toast.makeText(activity, getString(R.string.txt_savinginprogress), Toast.LENGTH_SHORT).show()
       }
}

Это наизнанку. Диспетчер верхнего уровня должен оставаться как есть (Main) и в withContext(IO) должна идти только работа по блокировке

Marko Topolnik 10.12.2020 13:01

Приводит ли их обмен к проблемам с производительностью или это противоречит лучшим практикам?

Andrew Chelix 10.12.2020 13:09

Есть некоторые теоретические проблемы с производительностью, такие как передача в поток ввода-вывода только для немедленной передачи обратно в поток пользовательского интерфейса, но это не так важно. Это просто делает код более уродливым и трудным для понимания, когда вы делаете это таким образом. OTOH, это зависит от варианта использования, если у вас много вызовов ввода-вывода и только один доступ к пользовательскому интерфейсу в середине, этот способ может привести к лучшему коду.

Marko Topolnik 10.12.2020 13:10

Другие вопросы по теме