Обновление пользовательского интерфейса в сопрограмме после Activity.onDestroy () - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть этот код в моей деятельности:

private val job = Job()
private val ioScope = CoroutineScope(Dispatchers.IO + job)
private val uiScope = CoroutineScope(Dispatchers.Main + job)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_second)

    ioScope.launch {
        delay(3000L)
        textView.text = "test1"
        uiScope.launch {
            textView.text = "test2"
        }
    }
}

Если я запускаю и жду 3 секунды, приложение вылетает с CalledFromWrongThreadException, что предсказуемо, потому что я обновляю пользовательский интерфейс из фонового потока в строке textView.text = "test1".

Но если я нажму кнопку назад, я вижу, что будут вызваны onPause () и onDestroy (), но будут вызваны обе строки textView.text = "test1" в фоновом потоке и textView.text = "test1" в потоке пользовательского интерфейса, но без исключения.

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

Безопасно ли писать код таким способом?Например, выполнять сетевой вызов и обновлять пользовательский интерфейс после ответа (когда активность может быть уничтожена), или могут быть некоторые проблемы?

1 Ответ

0 голосов
/ 04 февраля 2019

Вы в основном вызываете (временную) утечку памяти, не отменяя сопрограмму.Обновление представления после уничтожения действия на самом деле не приведет к возникновению какого-либо исключения;скорее, изменения просто не будут отражены в любом пользовательском интерфейсе.Вы обновляете значения в Деятельности, которая была отброшена, но сохранена в памяти только из-за того, что ваша сопрограмма сохранила ссылку на нее.

Как упоминает @Sergey, вы должны job.cancel() in onDestroy().

...