소개

3장_라이프 사이클과 에러 핸들링

2장에서는 안드로이드 UI 스레드에서 네트워크를 요청하면 블로킹이 발생하여, 네트워크에서 코루틴을 사용하고 결과만 UI 스레드에서 합쳐서 쓰는 것을 익혔음
3장에서는 두가지 유형의 비동기 작업
Job
Deferred
비동기 함수의 쉽게 나눠볼 수 있는 두가지
결과가 없는 비동기 ⇒ job
로그를 기록하고 전송하는 것을 백그라운드 작업으로 하는데, 이것이 완료되고 있는지 여부는 검사하지 않는다.
물론 큐에 일정 수준 이상 찬것을 노티받기는 함
결과를 반환하는 비동기 ⇒ deferred
결과를 활용해야되는 경우
여러 상태정보를 가져올때
물론 두가지 경우다 예외가 발생하거나, 해당작업이 필요하지 않을때 취소를 할 수 있음
Job
fire and forget
예외가 발생하지 않는한 대기하지 않는다
fun main(args: Array<String> = runBlocking { val job = GlobalScope.launch { } }
Kotlin
복사
launch 를 사용해 잡을 생성함 or Job()
JobSupport 구현체를 사용
예외처리
Job 내부에서 발생한 예외는 Job을 생성한 곳까지 전파됨
현재 스레드에 Uncauht Exception Handler에 예외가 전파됨
라이프 사이클
New → 실행 안된 job
Active → 실행 중인 job
Canceling → 실행 중인 job에서 cancel() 호출되면 취소완료 될때까지의 상태
Cancelled → 취소로 인해 완료된 Job (completed로 분류하기도 함)
Completed → 더 이상 실행이 불가능한 Job
Deferred
결과를 반환하는 비동기 작업
promise, futures
연산은 객체를 반환하고, 비동기 작업이 완료될때까지 객체가 비어있음
deferred를 만들려면 async, await으로 만들 수 있음
예외처리
예외를 자동으로 전파하지 않음(Job과 다른점)
결과를 대기할 것으로 예상하기 때문
실행이 성공했는지 확인하는 것이 사용자의 몫
예외처리 전파 안됨
val deferred = GlobalScope.async { } delay(2000)
Kotlin
복사
예외처리 전파 됨
val deferred = GlobalScope.async { } deferred.await()
Kotlin
복사
CoroutineExceptionHandler 를 job 처럼 동일하게 사용가능
상태는 한 방향으로만 감
Job이 완료된 경우 다시 실행 불가능
안드로이드 예시 ⇒ RSS 여러 피드에서 동시에 읽기
rss 피드 리스트를 등록해서, 각 피드의 정보를 취합하는 앱을 만듬
async, await으로 처음 구성함
피드 url 정보가 잘못되면 await에서 에러를 뿜으며 화면 정지
deferred 예외처리
await 대신 join
await는 예외가 바로 전파됨
join을 써서 에러가 전파되지 않게 함
feeds.mapTo(requests) { asyncFetchHeadlines(it, dispatcher) } requests.forEach { it.join() }
Kotlin
복사
각 피드 응답 합치기
getCompleted() 으로 요청 결과 가져오기
isCancelled → true일땐 getCompeleted()가 에러 전파됨
isCancelled가 true인 애들 갯수와 에러만 따로 모아서 보여주기
val failed = requests .filter { it.isCancelled } .size
Kotlin
복사
isCancelled → false인 완료된 애들만 getCompleted() 으로 병합해야됨
val headlines = requests .filter { !it.isCancelled } .flatMap { it.getCompleted() }
Kotlin
복사