비동기 처리가 끝나기 전에 [Kotlin] 대기

하고 싶은 일


coroutine 등과 대응하지 않는 코드로 콜백 등 비동기 처리의 완성을 사용하지 않고 간단하게 기다립니다.

과제.


이런 코드는result의 획득 시기를 제어하기 어렵다.
# 処理完了時に result or password が呼ばれる。
# その間、処理は中断されず次の行へ進む
Amplify.Auth.signIn(
    username,
    password,
    { result ->
        Log.i(
            "AuthQuickstart",
            if (result.isSignInComplete) "Sign in succeeded" else "Sign in not complete"
        )
    },
    { error -> Log.e("AuthQuickstart", error.toString()) }
)
AWS Amplify: https://docs.amplify.aws/lib/auth/getting-started/q/platform/android#configure-auth-category

해결책


suspendCoroutine 사용


LoginRepository.kt
import com.amplifyframework.core.Amplify
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

sealed class Result<out R> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
}

class LoginRepository {
    suspend fun makeLoginRequest(username: String, password: String): Result<String> {
        return suspendCoroutine { continuation ->
            Amplify.Auth.signIn(
                username,
                password,
                { res ->
                    val result =
                        Result.Success(if (res.isSignInComplete) "Sign in succeeded" else "Sign in not complete")
                    continuation.resume(result)
                },
                { error ->
                    val result = Result.Error(Exception(error.toString()))
                    continuation.resume(result)
                }
            )
        }
    }
}
continuation.resume에 호출되기 전suspendCoroutine에 대기하고 continuation.resume(result)result로 돌아간다.

소환자


로그인 처리가 완료될 때까지 기다린 후 startMainActivity() 호출됩니다.
MainActivity.kt
private fun login(username: String, password: String) = MainScope().launch(Dispatchers.Main) {
    when (val result = loginRepository.makeLoginRequest(username, password)) {
        is Result.Success<String> -> Log.i("LoginActivity", result.data)
        else -> Log.e("LoginActivity", result.toString())
    }
    startMainActivity()
}

suspend Coroutine 소개


https://droidkaigi.github.io/codelabs-kotlin-coroutines-ja/#6
이 점이 괜찮다고 하겠지, 이걸 읽으면 이 기사는 필요 없겠지...

후기


굿 실천이 아니라고 생각해요.
이번에 예를 들어 설명한 Amplify에서 더 좋은 형식을 논의했다.
https://github.com/aws-amplify/amplify-android/issues/605

폐물

  • https://zenn.dev/tktcorporation/scraps/5f2088b0fdc3f5
  • 참고 자료

  • https://stackoverflow.com/questions/62270000/how-to-save-data-from-a-kotlin-asynchronous-closure
  • 좋은 웹페이지 즐겨찾기