等待另一种方法,直到协程完成 [Android Kotlin]

Make wait another method until coroutine finishes [Android Kotlin]

我想创建等待方法 getCurrentUser 或通知该方法,直到协程完成。因为在协程中初始化的变量 conversationKit 在方法中使用。协程在方法 integrateConversationKit 中启动。两种方法都在 onCreate 中调用 MainActivity。但是我收到错误 lateinit 属性 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()
            }
    }

您可以使用 Flows 来响应地更新 conversationKit,然后 return 它是第一个非空值

 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()
            
    }

我只想让 getCurrentUser 成为一个挂起调用,从缓存结果的内部挂起调用中获取 ConversationKit

   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 值意味着检索该值时出错。您还可以将其包装在某种 Result 中,以便 return 成功/失败而不是可为 null 的值。

不过,如果您真正想做的是使 getCurrentUser 成为一个不需要协程即可使用的非挂起 阻塞调用 那么你可以使用 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
       }          
   }

不过我真的不推荐这种方法。