코루틴
코루틴 이란 ? 비동기적으로 실행되는 코드를 간소화 하기 위해 안드로이드에서 사용할 수 있는 동시 실행 설계 패턴입니다.
- 경량 : 코루틴은 실행중인 스레드를 차단하지 않는 정지를 지원하므로 단일 스레드에서 많은 코루틴을 실행할 수 있습니다.
- 메모리 누수 감소 : 구조화된 동시 실행을 사용하여 범위 내에서 작업을 실행합니다.
- 기본으로 제공되는 취소 지원 : 실행 중인 코루틴 계층 구조를 통해 취소가 전달됩니다.
- 이외 Jetpack 지원등..
백그라운드 스레드에서 실행
기본 스레드에서 네트워크 요청을 보내면 응답을 받을 때까지 스레드가 대기하거나 차단됩니다.
스레드가 차단될 경우 앱이 정지되고 응답없음(ANR) 대화상자가 표시될 수 있습니다.
이것의 해결방식으로 네트워크 요청을 새로운 코루틴을 만들고 I/O스레드에서 네트워크 요청을 실행할 수 있습니다.
example 1)
class LoginViewModel(
private val loginRepository: LoginRepository
): ViewModel() {
fun login(username: String, token: String) {
// Create a new coroutine to move the execution off the UI thread
viewModelScope.launch(Dispatchers.IO) {
val jsonBody = "{ username: \\"$username\\", token: \\"$token\\"}"
loginRepository.makeLoginRequest(jsonBody)
}
}
}
- viewModelScope는 사전 정의된 CoroutineScope 입니다. 모든 코루틴은 코루틴범위 내에서 실행해야 합니다. CoroutineScope는 하나 이상의 관련 코루틴을 관리합니다.
- launch는 코루틴을 만들고 함수 본문의 실행을 해당하는 디스패처에 전달하는 함수입니다.
- Dispatchers.IO는 이 코루틴을 I/O작업용으로 예약된 스레드에서 해야 함을 나타냅니다.
기본 안전을 위해 코루틴 사용
기본 스레드에서 UI 업데이트를 차단하지 않는 한수를 기본 안전 함수로 간주합니다. 기본스레드에서 네트워크 요청을 하면 UI가 차단되므로 이 네트워크 요청이 담긴 함수는 기본 안전 함수가 아닙니다.
코루틴 라이브러리의 withContext() 함수를 사용하여 코루틴 실행을 다른 스레드로 이동합니다.
example 2)
class LoginRepository(...) {
...
suspend fun makeLoginRequest(
jsonBody: String
): Result<LoginResponse> {
// Move the execution of the coroutine to the I/O dispatcher
return withContext(Dispatchers.IO) {
// Blocking network request code
}
}
}
- withContext(Dispatcher.IO)는 코루틴 실행을 I/O스레드로 이동하여 호출 함수를 기본 안전 함수로 만들고 필요에 따라 UI를 업데이트 하도록 설정합니다.
- makeLoginRequest 에는 supsend 키워드가 표시됩니다. suspend키워드는 코루틴 내에서 함수가 호출되도록 강제하는 Kotlin의 방법입니다.
example 3)
class LoginViewModel(
private val loginRepository: LoginRepository
): ViewModel() {
fun login(username: String, token: String) {
// Create a new coroutine on the UI thread
viewModelScope.launch {
val jsonBody = "{ username: \\"$username\\", token: \\"$token\\"}"
// Make the network call and suspend execution until it finishes
val result = loginRepository.makeLoginRequest(jsonBody)
// Display result of the network request to the user
when (result) {
is Result.Success<LoginResponse> -> // Happy path
else -> // Show error in UI
}
}
}
}
다시 example 1을 수정한 버전을 살펴봅시다.
- launch가 Dispatchers.IO 매개변수를 사용하지 않습니다. Dispatcher를 launch에 전달하지 않으면 코루틴은 기본 스레드에서 실행됩니다.
- 앱이 기본스레드의 View 레이어에서 login 함수를 호출합니다.
- launch가 기본 스레드에서 네트워크 요청을 보낼 때 코루틴을 만들며, 코루틴이 실행을 시작합니다.
- 코루틴 내에서 makeLoginRequest 호출은 withContext 블록 실행이 끝날 때 까지 코루틴의 추가 실행을 정지합니다 (ViewmodelScope의 코루틴의 코드를 makeLoginRequest의 withContext 블록 실행이 끝날때까지 일시 정지하고 끝난 후 부터 다시 실행합니다.)
- withContext블록이 완료되면 네트워크 요청 결과와 함께 기본 스레드에서 실행을 재개합니다.
출처 : https://developer.android.com/kotlin/coroutines?hl=ko
'안드로이드' 카테고리의 다른 글
[Android] Chronometer를 이용한 스톱워치 구현 (0) | 2022.06.08 |
---|---|
[Android] 안드로이드 이동 경로 추적 (1) (0) | 2022.05.31 |
[Kotlin] 고차함수와 람다식에 대하여 (0) | 2022.01.04 |
안드로이드 SNS 로그인 릴리즈키 얻기 (1) (0) | 2021.06.17 |
안드로이드 SNS 로그인 연동하기 4. 애플 로그인 (0) | 2021.06.02 |