我有一个URL列表,我想遍历列表以加载每个URL,但当try 这样做时,迭代失败,它只加载列表的最后一项.

最初,此URL是在WebView首次开始运行时加载的:

webView.loadUrl("https://translate.google.com/?sl=$from&tl=$into&text=Hello&op=translate")

我有一个要遍历它们的URL列表:

 val items = listOf(
        "https://translate.google.com/?sl=$from&tl=$into&text=First text&op=translate",
        "https://translate.google.com/?sl=$from&tl=$into&text=Second text&op=translate",
        "https://translate.google.com/?sl=$from&tl=$into&text=Third text&op=translate"
    )

页面加载完成后,我遍历列表以加载每个URL:

webView.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                GlobalScope.launch {
                    delay(5000)
                    withContext(Dispatchers.Main) {
                        items.forEach {
                            view?.loadUrl(it)
                            injectJavascript(view)
                        }
                    }
                }
            }
        }

我只得到了最后一个URL的结果,也就是"第三个文本",有什么问题吗?我怎么才能让代码工作呢?

推荐答案

The problem you are facing is due to the fact that WebView's loadUrl() function operates asynchronously.
When you call loadUrl() in your forEach loop, it initiates the loading of the URL, but it does not wait for the page to finish loading before proceeding to the next URL.
Consequently, the loop quickly iterates over all the URLs and only the last URL has the chance to fully load, which is why you are only seeing the result of the last URL.

为了处理这个问题,您可以使用类似队列的方法,仅在当前URL加载完成后才加载下一个URL.

例如:

val items = mutableListOf(
    "https://translate.google.com/?sl=$from&tl=$into&text=First text&op=translate",
    "https://translate.google.com/?sl=$from&tl=$into&text=Second text&op=translate",
    "https://translate.google.com/?sl=$from&tl=$into&text=Third text&op=translate"
)

var isLoading = false

webView.webViewClient = object : WebViewClient() {
    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
        super.onPageStarted(view, url, favicon)
        isLoading = true
    }

    override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)
        isLoading = false
    }
}

val handler = Handler(Looper.getMainLooper())
val runnable = object : Runnable {
    override fun run() {
        if (!isLoading && items.isNotEmpty()) {
            val nextUrl = items.removeAt(0)
            webView.loadUrl(nextUrl)
            injectJavascript(webView)
        }
        handler.postDelayed(this, 5000)
    }
}
handler.post(runnable)

在这一修订后的准则中:

Here, onPageStarted and onPageFinished are used to maintain a flag isLoading that indicates whether the WebView is currently loading a page or not.
The runnable object checks this flag, and if the WebView is not currently loading a page, it starts loading the next URL. This runnable object is posted to a Handler every 5 seconds.

这样,只有当WebView当前未加载页面时,才会加载下一个URL.

Kotlin相关问答推荐

在Kotlin中的嵌套when语句中,else块是强制性的吗?

如何让 LocalDateTime.parse 拒绝 24:00 时间

如何优雅地声明一个StateFlow?

Kotlin Path.useLines { } - 如何不获取 IOException("Stream closed")?

通用接口继承

如果不为空,则为 builder 设置一个值 - Kotlin

如何在 Compose 中创建可重用的修饰符?

Kotlin 1.2.21 + SimpleXml 2.3.0 - consume List error (must mark set get method)

`this@classname` 在 Kotlin 中是什么意思?

Kotlin - mutableMapOf() 会保留我输入的顺序

如何通过反射使用 Kotlin 对象

Kotlin 的类型具体化使哪些在 Java 或 Scala 中无法实现的成为可能?

如何将命令行参数传递给Gradle Kotlin DSL

Kotlin使用运行时断言进行空判断?

Kotlin 扩展函数 - 覆盖现有方法

大小写敏感性 Kotlin / ignoreCase

Kotlin数据类打包

Kotlin-将UTC转换为当地时间

Kotlin扩展函数与成员函数?

Kotlin - 为什么我会得到 KotlinNullPointerException