繁体   English   中英

在 Kotlin 中让 Coroutine 等待 Jsoup 响应

[英]Make Coroutine wait for Jsoup response in Kotlin

我是使用 Android 开发的新手,并且在理解事物的工作原理方面存在问题。 我制作了一个应用程序来从页面中抓取内容并下载元素,首先使用 AsyncTask 并工作,但由于 AsyncTask 不允许我在进行中与 UI Activity 进行通信,因此我决定更改为协程,检查了一个示例,然后我使用的相同代码似乎不起作用。

我使用了一些日志来尝试确定问题,并且似乎没有等待Jsoup请求。 协程首先调用方法scrapePage()下载 HTML 并抓取链接,然后调用downloadImages()将链接添加到 Android 的 DownloadManager。 在日志中Log.d("action", "Start Scraping")被打印,但Log.d("action", "Page downloaded")没有,我们仍然得到Log.d("action", "End")来自协程,这让我觉得不是等待 Jsoup 请求响应,而是带有空响应,导致其余代码无法正常工作。

下载服务.kt

object DownloadService {

    private val parentJob = Job()
    
    ...

    private val coroutineScope = CoroutineScope(Dispatchers.Main + parentJob +
            coroutineExceptionHandler)

    fun StartService(URL: String, location:String, contx:Context) {

        coroutineScope.launch(Dispatchers.Main) {
            Log.d("action", "Start")
            val links = scrapePage(URL)
            val download = downloadImages(links, location, contx)
            Log.d("action", "End")
        }
    }

    private suspend fun scrapePage(url: String): MainActivity.Scraped =
        withContext(Dispatchers.IO) {
            var URL = url
            var scrape = MainActivity.Scraped()
            try {
                Log.d("action", "Start Scraping")
                var response = Jsoup.connect(URL).get()
                Log.d("action", "Page downloaded")
                response.getElementsByClass("link").forEach {
                    /*Scrape URLs*/
                    Log.d("action", "Add "+link)
                }
            } catch (e: Exception) {
                when(e) {
                    is HttpStatusException -> {
                        System.out.println(e.getStatusCode())
                        scrape.error = true
                        error = true
                    }
                }
            }
            return@withContext scrape
        }

    ...
}

主活动.kt

class MainActivity : AppCompatActivity() {
    ...
    fun makeRequest(URL : String) {
        WorkingURL = URL
        var uri = ""
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            uri = MediaStore.Downloads.EXTERNAL_CONTENT_URI.toString()
            log.text = uri
        } else {
            uri = getStoragePath()
            log.text = uri
        }
        DownloadService.StartService(URL, uri, this)
        Log.d("links", DownloadService.getError().toString())
    }
}

我不确定问题出在哪里,也不知道从哪里开始搜索。 我知道Scraping的代码有效,因为我之前在 AsyncTask 中使用过它,所以问题似乎是将它传递给协程。

这里Jsoup.connect(URL).get()抛出错误。 因此,不会调用Log.d("action", "Page downloaded")

但是由于您正在处理异常,因此代码运行 catch 部分并完成挂起功能并转到downloadImages()


解决方案

首先,在scrapePage()函数的catch 部分添加日志并找出导致异常的原因。 代码中的其他所有内容都很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM