I want to make wait method getCurrentUser
or notify the method until the coroutine is finishes. Because variable conversationKit
which is initialised in coroutine is used in method. Coroutine is launched inside the method integrateConversationKit
.Both methods are invoking in onCreate
in MainActivity
. But I am getting the error lateinit property conversationKit has not been initialized.
class ConversationKitService(private val context: Context) {
private val scope = CoroutineScope(Dispatchers.Main)
lateinit var conversationKit: ConversationKit
fun integrateConversationKit() {
val job = scope.launch {
val result = conversationKitFactory.create(
settings = settings
)
when (result) {
is ConversationKitResult.Success -> conversationKit = result.value
is ConversationKitResult.Failure -> println(result.message)
}
}
}
fun getCurrentUser(): User? {
return conversationKit.getCurrentUser()
}
}
You could use a Flow
s for updating the conversationKit
reactively, then return it's first non-null value
class ConversationKitService(private val context: Context) {
private val scope = CoroutineScope(Dispatchers.Main)
private val conversationKit = MutableStateFlow<ConversationKit?>(null)
fun integrateConversationKit() {
val job = scope.launch {
val result = conversationKitFactory.create(
settings = settings
)
when (result) {
is ConversationKitResult.Success -> conversationKit.value = result.value
is ConversationKitResult.Failure -> println(result.message)
}
}
}
suspend fun getCurrentUser() = conversationKit.first{ it != null }.getCurrentUser()
}
I would just make the getCurrentUser
a suspend call that fetches the ConversationKit
from an internal suspend call that caches the result
class ConversationKitService(private val context: Context) {
@Volatile
private var conversationKit: ConversationKit? = null
...
suspend fun getCurrentUser() = getConversationKit()?.getCurrentUser()
private suspend getConversationKit(): ConversationKit? {
if (conversationKit != null) return conversationKit
val result = conversationKitFactory.create(settings = settings)
conversationKit = when (result) {
is ConversationKitResult.Success -> result.value
is ConversationKitResult.Failure -> null
}
return conversationKit
}
}
A null
value then implies an error to retrieve the value. You could also wrap that in some kind of Result
so that you return a success / failure rather than a nullable value.
If what you are really trying to do, though, is to make getCurrentUser
a non-suspending blocking call that doesn't require a coroutine to use it then you could use runBlocking
:
class ConversationKitService(private val context: Context) {
@Volatile
private var conversationKit: ConversationKit? = null
...
fun getCurrentUser() = runBlocking {
getConversationKit()?.getCurrentUser()
}
private suspend getConversationKit(): ConversationKit? {
if (conversationKit != null) return conversationKit
val result = conversationKitFactory.create(settings = settings)
conversationKit = when (result) {
is ConversationKitResult.Success -> result.value
is ConversationKitResult.Failure -> null
}
return conversationKit
}
}
I wouldn't really recommend this approach, though.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.