Приостановить `withTimeout` - PullRequest
       28

Приостановить `withTimeout`

0 голосов
/ 07 ноября 2019

Мое приложение запускается с выполнения сопрограммы:

model.viewModelScope.launch(Dispatchers.IO) {
            val timeout = withTimeoutOrNull(TIMEOUT) {
            //send some initialization server requests
            true   //timeout=true
    }
    if (timeout!=null){
        // app started ok
    } else {
        // app freezed on start
    }
}

Проблема заключается в одном из шагов инициализации - получите согласие пользователя на передачу его личных данных (GDPR). Форма согласия - это модальное всплывающее окно, которое ожидает ввода пользователя. Но таймер тикает все это время. Поэтому после gdpr пользователь может увидеть ошибку app starts too long.

Есть ли способ приостановить withTimeoutOrNull таймер и возобновить его через некоторое время?

1 Ответ

1 голос
/ 08 ноября 2019

Он не поддерживается "из коробки", но вы можете написать свою собственную версию withTimeoutOrNull, которая будет поддерживать таймер с паузой. Основная идея состоит в том, чтобы запустить ваш блок в отдельной coroutineScope { ... } и launch вторичной вспомогательной сопрограмме, которая отменяет эту область после истечения времени ожидания. Теперь, если вы сохраняете ссылку на этого помощника cancellationJob, вы можете отменить его, когда вам нужно приостановить свое время, и перезапустить его, когда вам нужно возобновить таймер.

Это дало бы вам по существу то же поведение, что и базовый withTimeout, но с добавленной паузой. Для реализации варианта withTimeoutOrNull требуется немного дополнительного кода. Вам нужно будет отловить исключение отмены и заменить его нулевым результатом.

В этой сущности можно найти отработанную реализацию: https://gist.github.com/elizarov/c5b0fde43ca14efbb8bcab13ad43c6ca

...