Есть много способов добиться этого, если вы используете Android в качестве базовой платформы, вы можете использовать нативный компонент под названием AsyncTask
хороший SO post о том, как его использовать.
Если вы хотите использовать kotlin как язык и предоставляемые им функции, вы можете попробовать использовать coroutines
ref .
Лично я бы порекомендовал coroutines
, это упрощает обработку исключений и ошибок, а также предотвращает ад обратного вызова.
вот пример того же кода в сопрограмме,
// global
private val mainScope = CoroutineScope(Dispatchers.MAIN + SupervisorJob())
// inside a method
mainScope.launch{
withContext(Dispatchers.IO){
// do your async task here, as you can see, you're doing this in an IO thread scope.
}
}