![](/img/trans.png)
[英]How to cancel (return from) a Kotlin coroutine from within the scope immediately?
[英]How to return a variable from inside coroutine scope in Kotlin
我在协程中有一个jsoup
function,它从网站上抓取信息,然后获取它抓取的所有信息的地图列表。 但是,每当我尝试返回列表时,都会返回:
"Function0<java.util.List<java.util.Map<java.lang.String, ? extends java.lang.String>>>"
这是 function 的代码:
suspend fun popularHome(
pg: String
): Any = withContext(Dispatchers.IO) {
val table = mutableListOf<Map<String, String>>()
val doc: Document = Jsoup
.connect("https://www.novelupdates.com/novelslisting/?sort=2&order=1&status=1&pg=$pg")
.userAgent("Mozilla/5.0")
.referrer("http://www.google.com")
.ignoreContentType(true)
.get()
val imageLists = doc.getElementsByClass("search_img_nu")
val lists = doc.getElementsByClass("search_main_box_nu")
for ((list, imageList) in lists.zip(imageLists)) {
val searches: Elements = list.getElementsByClass("search_title")
val imageSearches: Elements = imageList.getElementsByTag("img")
for ((search, imageSearch) in searches.zip(imageSearches)) {
val titles = search.getElementsByTag("a")
val ranks = search.getElementsByClass("genre_rank")
for ((title, rank) in titles.zip(ranks)) {
val link: String = title.attr("href") // Book Link
val titleName: String = title.text() // Book Title
val imageLink: String = imageSearch.attr("src") // Book Image Link
val rankName: String =
rank.text().replace("#", "") // Book Popularity Rank
table.add(
mutableMapOf<String, String>(
"rank" to rankName,
"title" to titleName,
"link" to link,
"image" to imageLink
)
)
}
}
}
Log.i("tag", table.toString())
return@withContext { table }
}
这是Main Activity
的代码:
package com.example.sushi
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
import com.example.sushi.service.repos.novelupdates.com.NovelUpdatesScraper
import com.example.sushi.ui.styling.SushiTheme
import kotlinx.coroutines.*
class MainActivity : ComponentActivity() {
val scrape = NovelUpdatesScraper()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SushiTheme {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Hey")
}
}
}
lifecycleScope.launch {
Log.i("tag", scrape.popularHome("1").toString())
}
}
}
无论我把退货放在哪里,除了一个空列表,我什么也得不到。 然而,当我记录列表时,它会为我提供所有被抓取的信息。
我已经尝试过这个解决方案: How to return a value inside a coroutine scope kotlin, android这个解决方案: How to return value from coroutine scope
在代码中,当您调用return@withContext { table }
时,意味着它将返回() -> List
而不是List
实例。
只需调用return@withContext table
,它就应该被修复。
顺便说一句,我相信你不应该将 function 返回类型设置为Any
。
如果你确切地知道你要做什么并且你期望这个 function 将返回一个 List 那么返回类型应该是List<Map<String, String>>
,没有理由将它设置为Any
。
可以看到的直接好处是,如果您将返回类型设置为List<Map<String, String>>
并调用return@withContext { table }
,Android Studio IDE 将告诉您哪里出了问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.