Android Studio - Korlin 协程 --> 未解决的引用:异步和启动
Android Studio - Korlin Coroutines --> Unresolved references: async & launch
我正在学习 Kotlin,我正在使用协程。
我在网上搜索了一下,是不是我用的方法太旧了?但我有异步和启动(UI)没有解决...
我的build.gradle:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
kotlin {
experimental {
coroutines 'enable'
}
}
...
dependencies {
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'org.jetbrains.kotlin:kotlin-serialization'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
implementation 'org.jetbrains.anko:anko-commons:0.10.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
从 api 获取数据的代码(已更新)
//getting data from api
fun fetchCharacterData(): Deferred<CharachterGenerator.CharacterData> {
CoroutineScope(Main).launch {
async { val apiData = URL(CHARACTER_DATA_API).readText()
CharachterGenerator.fromApiData(apiData)
}
}
return <--- how to get this correct, what should I return?
}
我在按钮 setOnClickListener 中使用启动
generateButton.setOnClickListener {
CoroutineScope(Main).launch {
characterData = fetchCharacterData().await()
displayCharacterData()
}
}
displayCharacterData()
}
请告诉我,我还在学习...
launch
和async
是CoroutineScope的成员函数。你不能直接调用它们,除非你从一个实现了 CoroutineScope 的 class 中调用它们。您可能已经在 Kotlin 文档中看到了这一点,但它们的大多数示例都在 runBlocking
lambda 中使用,它提供了一个作用域作为函数接收器。在 Android 上,您通常会使用提供给您的 CorotuineScopes,例如 lifecycleScope
或 viewModelScope
。
更新后编辑:
异步执行某事并return结果的函数的常见模式不是return延迟,而是使其成为直接return结果的挂起函数使用 withContext
:
suspend fun fetchCharacterData() = withContext(Dispatchers.IO) {
val apiData = URL(CHARACTER_DATA_API).readText()
CharachterGenerator.fromApiData(apiData)
}
然后当你调用它时你的代码非常简单,因为你不必担心你在哪个调度程序上:
generateButton.setOnClickListener {
lifecycleScope.launch {
characterData = fetchCharacterData()
displayCharacterData()
}
}
使用类似于 CoroutineScope()
构造函数的函数来创建您未存储在 属性 中的一次性作用域是错误的,您可以在其中管理其生命周期。您应该很少需要创建自己的,因为 Android 为您提供 lifecycleScope
和 viewModelScope
并代表您管理它们的生命周期。
在浏览了其他几个文档之后,我设法做到了这一点
使用异步调用 API:
fun fetchCharacterData(): Deferred<CharachterGenerator.CharacterData> {
return CoroutineScope(IO).async { val apiData = URL(CHARACTER_DATA_API).readText()
CharachterGenerator.fromApiData(apiData)
}
}
发出请求并获取结果然后发送以显示
generateButton.setOnClickListener {
CoroutineScope(Main).launch {
characterData = fetchCharacterData().await()
displayCharacterData()
}
}
我正在学习 Kotlin,我正在使用协程。
我在网上搜索了一下,是不是我用的方法太旧了?但我有异步和启动(UI)没有解决...
我的build.gradle:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
kotlin {
experimental {
coroutines 'enable'
}
}
...
dependencies {
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'org.jetbrains.kotlin:kotlin-serialization'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
implementation 'org.jetbrains.anko:anko-commons:0.10.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
从 api 获取数据的代码(已更新)
//getting data from api
fun fetchCharacterData(): Deferred<CharachterGenerator.CharacterData> {
CoroutineScope(Main).launch {
async { val apiData = URL(CHARACTER_DATA_API).readText()
CharachterGenerator.fromApiData(apiData)
}
}
return <--- how to get this correct, what should I return?
}
我在按钮 setOnClickListener 中使用启动
generateButton.setOnClickListener {
CoroutineScope(Main).launch {
characterData = fetchCharacterData().await()
displayCharacterData()
}
}
displayCharacterData()
}
请告诉我,我还在学习...
launch
和async
是CoroutineScope的成员函数。你不能直接调用它们,除非你从一个实现了 CoroutineScope 的 class 中调用它们。您可能已经在 Kotlin 文档中看到了这一点,但它们的大多数示例都在 runBlocking
lambda 中使用,它提供了一个作用域作为函数接收器。在 Android 上,您通常会使用提供给您的 CorotuineScopes,例如 lifecycleScope
或 viewModelScope
。
更新后编辑:
异步执行某事并return结果的函数的常见模式不是return延迟,而是使其成为直接return结果的挂起函数使用 withContext
:
suspend fun fetchCharacterData() = withContext(Dispatchers.IO) {
val apiData = URL(CHARACTER_DATA_API).readText()
CharachterGenerator.fromApiData(apiData)
}
然后当你调用它时你的代码非常简单,因为你不必担心你在哪个调度程序上:
generateButton.setOnClickListener {
lifecycleScope.launch {
characterData = fetchCharacterData()
displayCharacterData()
}
}
使用类似于 CoroutineScope()
构造函数的函数来创建您未存储在 属性 中的一次性作用域是错误的,您可以在其中管理其生命周期。您应该很少需要创建自己的,因为 Android 为您提供 lifecycleScope
和 viewModelScope
并代表您管理它们的生命周期。
在浏览了其他几个文档之后,我设法做到了这一点
使用异步调用 API:
fun fetchCharacterData(): Deferred<CharachterGenerator.CharacterData> {
return CoroutineScope(IO).async { val apiData = URL(CHARACTER_DATA_API).readText()
CharachterGenerator.fromApiData(apiData)
}
}
发出请求并获取结果然后发送以显示
generateButton.setOnClickListener {
CoroutineScope(Main).launch {
characterData = fetchCharacterData().await()
displayCharacterData()
}
}