Не могу вернуть ArrayList из потока после парсинга

У меня есть отдельный класс, метод в котором генерирует мне ArrayList. В нем обычный поток, а в потоке в try/catch парсится и наполняется инфой ArrayList. Дальше этот ArrayList нужно как-то вернуть из try/catch(с этим разобрался в принципе) и вернуть из потока(а вот с этим нет). Говорят юзать корутины, но там для меня та же проблема. Пока единственным решением видится... async task

val url: String = "https://ranobelib.ru/ranobe/"

    fun listMain(): ArrayList<String> {
        Thread {
            var listMain = ArrayList<String>()
            try {
                val document: Document = Jsoup.connect(url)
                    .userAgent(
                        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
                                "(KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
                    )
                    .timeout(100000).get()
                val items: Elements = document.getElementsByClass("item")
                for (item in items) {
                    listMain.add(
                        BookData(
                            item.select("a").text(),
                            item.select("a").text(),
                            item.select("img").first().attr("src"),
                            item.select("a").first().attr("href")
                        ).toString()
                    )
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }.start()
        return listMain
    }

BookData:

data class BookData(
    var title: String,
    var info: String,
    var image_url: String,
    var book_url: String
)

Ответы (2 шт):

Автор решения: ЮрийСПб

Запрос в сеть должен происходить не на главном потоке, асинхронно. Засим нельзя написать код такого рода:

fun getDataFromNetwork() : Something { 
    /* Тут асинхронный код, который неизвестно сколько будет выполнятся
       и выполнится ли вообще успешно. 
       Вдруг сети нет или она пропадёт в процессе или сервер сломается */ 
}

Соответственно, вы не сможете этот метод использовать из главного потока так:

someView.showDataOnScreen(getDataFromNetwork())

Поступать надо иначе: только в тот момент, когда будет успешно завершён сетевой запрос - вызвать код, который полученные данные выведет на экран. Выглядеть это может примерно так:

fun getDataFromNetwork() {
    /* Тут асинхронный код, который неизвестно сколько будет выполнятся
       и выполнится ли вообще успешно. 
       Вдруг сети нет или она пропадёт в процессе или сервер сломается */ 
    showDataOnScreen(variableWithDataFromNetwork)
}

fun showDataOnScreen(variableWithDataFromNetwork: Something) {
    someView.showDataOnScreen(variableWithDataFromNetwork)
}

Важно запускать showDataOnScreen() на главном потоке. Сделать это можно по разному. Если этот метод в активити - то всё его содержимое вызывайте через runOnUiThread() метод активити.

→ Ссылка
Автор решения: akella122

Решил вот так.

MainActivity.OnCreate():

GlobalScope.launch(){
            var listMain = listMain()
            withContext(Dispatchers.Main) {
                val MainAdapter: RecyclerView.Adapter<*> = MainAdapter(listMain)
                books_recycler.adapter = MainAdapter
            }
        }

Parser:

companion object {
        @JvmStatic
        fun listMain(): ArrayList<String> {
            var listMain = ArrayList<String>()
            try {
                val document: Document = Jsoup.connect("https://ranobelib.ru/ranobe/")
                    .userAgent(
                        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
                                "(KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
                    )
                    .timeout(100000).get()
                val items: Elements = document.getElementsByClass("item")
                for (item in items) {
                    listMain.add(
                        BookData(
                            item.select("a").text(),
                            item.select("a").text(),
                            item.select("img").first().attr("src"),
                            item.select("a").first().attr("href")
                        ).toString()
                    )
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
            return listMain
        }
    }
→ Ссылка