코루틴(Coroutine)
CoroutineScope
[ 코루틴이 실행되는 범위. 코루틴을 실행하고 싶은 Lifecycle에 따라
원하는 Scope를 생성하여 코루틴이 실행될 작업 범위를 지정할 수 있음 ]
1. 사용자 지정 CoroutineScope : CoroutineScope(CoroutineContext)
// 메인 쓰레드에서 실행될 사용자 정의 Scope
val scope = CoroutineScope(Dispatchers.Main)
scope.launch {
// 메인 쓰레드 작업
}
// 백그라운드에서 실행될 사용자 정의 Scope
CoroutineScope(Dispatchers.IO).launch {
// 백그라운드 작업
}
2. GlobalScope : 앱이 실행될 때부터 종료될 때까지 실행
// 앱의 라이프사이클동안 실행될 Scope
GlobalScope.launch {
// 백그라운드로 전환하여 작업
launch(Dispatchers.IO) {
}
// 메인쓰레드로 전환하여 작업
launch(Dispatchers.Main) {
}
}
3. ViewModelScope : ViewModel 대상, ViewModel이 제거되면 코루틴 작업 자동 취소
class MyViewModel: ViewModel() {
init {
viewModelScope.launch {
// ViewModel이 제거되면 코루틴도 자동으로 취소됩니다.
}
}
}
4. LifeCycleScope : Lifecycle 객체 대상(Activity, Fragment, Service...), LifeCycle이 끝날 때 코루틴 작업 자동 취소
class MyActivity : AppCompatActivity() {
init {
lifecycleScope.launch {
// Lifecycle이 끝날 때 코루틴 작업이 자동으로 취소됩니다.
}
}
}
5. liveData : LiveData 대상, LiveData가 활성화되면 실행을 시작하고 비활성화되면 자동 취소
val user: LiveData<User> = liveData {
val data = repository.loadUser() // suspend function
emit(data)
}
CoroutineContext
[ 코루틴 작업을 어떤 스레드에서 실행할 것인지에 대한 동작을 정의하고 제어하는 요소 ]
[ 주요 요소 : Job, Dispatchers ]
1. Job : 코루틴을 고유하게 식별, 코루틴 제어
val job = CoroutineScope(Dispatchers.IO).launch {
// 비동기 작업
}
job.join() // 작업이 완료되기까지 대기
job.cancel() // 작업 취소
val job1 = Job()
CoroutineScope(job1 + Dispatchers.Main).launch {
// 메인 쓰레드 작업
launch(Dispatchers.IO) {
// 비동기 작업
}
withContext(Dispatchers.Default) {
// 비동기 작업
}
}
val job2 = CoroutineScope(Dispatchers.IO).launch {
// 비동기 작업
}
job1.cancel() // job1이 연결된 코루틴 작업 취소
2. Dispatchers : 코루틴을 어떤 쓰레드에서 실행할 것인지에 대한 동작 지정
1) Dispatchers.Main : 안드로이드 메인 쓰레드, UI 작업을 위해 사용. ex) UI 구성, LiveData 업데이트
2) Dispatchers.IO : 네트워크, 디스크 I/O 실행에 최적화 ex) Retrofit으로 네트워크 통신, File이나 Room에서 데이터를 읽고 쓸 때
3) Dispatchers.Default : CPU 사용량이 많은 무거운 작업 처리에 최적화 ex) 데이터 가공, 복잡한 연산, JSON 파싱
CoroutineBuilder
[ 코루틴을 실행시켜 주는 함수 ]
[ launch, async ]
1. launch : Job 객체, 결과값 반환 x. 실행 후 결과값이 필요 없는 모든 작업을 실행
CoroutineScope(Dispatchers.Main).launch {
// 결과값이 필요없는 작업
}
2. async : Deferred 객체, 결과값 반환. await() 함수를 사용하여 코루틴 작업의 최종 결과값 반환
val deferred = CoroutineScope(Dispatchers.Main).async {
// 결과값
"Hello Coroutine!"
}
val message = deferred.await() // await()함수로 결과값 반환
println(message)
3. withContext
- async와 동일하게 결과값 반환. 차이점은 await()을 호출할 필요가 없다는 것.
- async{ }.await() 과 동일하게 작동
- 코루틴 내부나 suspend 함수 안에서 구현 가능. 콜백 필요 없이 코드의 쓰레드풀 제어 가능하기 때문에
네트워크 요청 or DB 조회 같은 작업에 주로 사용
init {
viewModelScope.launch { // Dispatchers.Main
val user = getUserInfo() // Dispatchers.Main
}
}
suspend fun getUserInfo(): User = // Dispatchers.Main
withContext(Dispatchers.IO) { // Dispatchers.IO
val response = apiService.getUserInfo() // Dispatchers.IO
if (response.isSuccessful) { // Dispatchers.IO
return@withContext response.body() // Dispatchers.IO
} else { // Dispatchers.IO
return@withContext null // Dispatchers.IO
} // Dispatchers.IO
} // Dispatchers.Main
Suspend Function
코루틴의 실행이 일시중단(suspend)되거나 다시 재개(resume)될 수 있기 때문에,
컴파일러에게 이 메소드는 코루틴 안에서 실행할 메소드임을 정의하기 위해 메소드명 앞에 “suspend”를 붙여줘야 함
suspend fun getUser(): User {
...
return user
}
'Android' 카테고리의 다른 글
[Android] Activity란? (0) | 2022.08.09 |
---|---|
[Android] BottomNavigation + ViewPager2 (0) | 2022.04.06 |
[Android] 액티비티 컴포넌트 - 액티비티 ANR 문제와 코루틴 (0) | 2022.01.05 |
[Android] 액티비티 컴포넌트 - 액티비티 생명주기 (0) | 2022.01.05 |
[Android] 액티비티 컴포넌트 - 인텐트 (0) | 2022.01.05 |
코루틴(Coroutine)
CoroutineScope
[ 코루틴이 실행되는 범위. 코루틴을 실행하고 싶은 Lifecycle에 따라
원하는 Scope를 생성하여 코루틴이 실행될 작업 범위를 지정할 수 있음 ]
1. 사용자 지정 CoroutineScope : CoroutineScope(CoroutineContext)
// 메인 쓰레드에서 실행될 사용자 정의 Scope
val scope = CoroutineScope(Dispatchers.Main)
scope.launch {
// 메인 쓰레드 작업
}
// 백그라운드에서 실행될 사용자 정의 Scope
CoroutineScope(Dispatchers.IO).launch {
// 백그라운드 작업
}
2. GlobalScope : 앱이 실행될 때부터 종료될 때까지 실행
// 앱의 라이프사이클동안 실행될 Scope
GlobalScope.launch {
// 백그라운드로 전환하여 작업
launch(Dispatchers.IO) {
}
// 메인쓰레드로 전환하여 작업
launch(Dispatchers.Main) {
}
}
3. ViewModelScope : ViewModel 대상, ViewModel이 제거되면 코루틴 작업 자동 취소
class MyViewModel: ViewModel() {
init {
viewModelScope.launch {
// ViewModel이 제거되면 코루틴도 자동으로 취소됩니다.
}
}
}
4. LifeCycleScope : Lifecycle 객체 대상(Activity, Fragment, Service...), LifeCycle이 끝날 때 코루틴 작업 자동 취소
class MyActivity : AppCompatActivity() {
init {
lifecycleScope.launch {
// Lifecycle이 끝날 때 코루틴 작업이 자동으로 취소됩니다.
}
}
}
5. liveData : LiveData 대상, LiveData가 활성화되면 실행을 시작하고 비활성화되면 자동 취소
val user: LiveData<User> = liveData {
val data = repository.loadUser() // suspend function
emit(data)
}
CoroutineContext
[ 코루틴 작업을 어떤 스레드에서 실행할 것인지에 대한 동작을 정의하고 제어하는 요소 ]
[ 주요 요소 : Job, Dispatchers ]
1. Job : 코루틴을 고유하게 식별, 코루틴 제어
val job = CoroutineScope(Dispatchers.IO).launch {
// 비동기 작업
}
job.join() // 작업이 완료되기까지 대기
job.cancel() // 작업 취소
val job1 = Job()
CoroutineScope(job1 + Dispatchers.Main).launch {
// 메인 쓰레드 작업
launch(Dispatchers.IO) {
// 비동기 작업
}
withContext(Dispatchers.Default) {
// 비동기 작업
}
}
val job2 = CoroutineScope(Dispatchers.IO).launch {
// 비동기 작업
}
job1.cancel() // job1이 연결된 코루틴 작업 취소
2. Dispatchers : 코루틴을 어떤 쓰레드에서 실행할 것인지에 대한 동작 지정
1) Dispatchers.Main : 안드로이드 메인 쓰레드, UI 작업을 위해 사용. ex) UI 구성, LiveData 업데이트
2) Dispatchers.IO : 네트워크, 디스크 I/O 실행에 최적화 ex) Retrofit으로 네트워크 통신, File이나 Room에서 데이터를 읽고 쓸 때
3) Dispatchers.Default : CPU 사용량이 많은 무거운 작업 처리에 최적화 ex) 데이터 가공, 복잡한 연산, JSON 파싱
CoroutineBuilder
[ 코루틴을 실행시켜 주는 함수 ]
[ launch, async ]
1. launch : Job 객체, 결과값 반환 x. 실행 후 결과값이 필요 없는 모든 작업을 실행
CoroutineScope(Dispatchers.Main).launch {
// 결과값이 필요없는 작업
}
2. async : Deferred 객체, 결과값 반환. await() 함수를 사용하여 코루틴 작업의 최종 결과값 반환
val deferred = CoroutineScope(Dispatchers.Main).async {
// 결과값
"Hello Coroutine!"
}
val message = deferred.await() // await()함수로 결과값 반환
println(message)
3. withContext
- async와 동일하게 결과값 반환. 차이점은 await()을 호출할 필요가 없다는 것.
- async{ }.await() 과 동일하게 작동
- 코루틴 내부나 suspend 함수 안에서 구현 가능. 콜백 필요 없이 코드의 쓰레드풀 제어 가능하기 때문에
네트워크 요청 or DB 조회 같은 작업에 주로 사용
init {
viewModelScope.launch { // Dispatchers.Main
val user = getUserInfo() // Dispatchers.Main
}
}
suspend fun getUserInfo(): User = // Dispatchers.Main
withContext(Dispatchers.IO) { // Dispatchers.IO
val response = apiService.getUserInfo() // Dispatchers.IO
if (response.isSuccessful) { // Dispatchers.IO
return@withContext response.body() // Dispatchers.IO
} else { // Dispatchers.IO
return@withContext null // Dispatchers.IO
} // Dispatchers.IO
} // Dispatchers.Main
Suspend Function
코루틴의 실행이 일시중단(suspend)되거나 다시 재개(resume)될 수 있기 때문에,
컴파일러에게 이 메소드는 코루틴 안에서 실행할 메소드임을 정의하기 위해 메소드명 앞에 “suspend”를 붙여줘야 함
suspend fun getUser(): User {
...
return user
}
'Android' 카테고리의 다른 글
[Android] Activity란? (0) | 2022.08.09 |
---|---|
[Android] BottomNavigation + ViewPager2 (0) | 2022.04.06 |
[Android] 액티비티 컴포넌트 - 액티비티 ANR 문제와 코루틴 (0) | 2022.01.05 |
[Android] 액티비티 컴포넌트 - 액티비티 생명주기 (0) | 2022.01.05 |
[Android] 액티비티 컴포넌트 - 인텐트 (0) | 2022.01.05 |