일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- rx
- Koin
- 테스트 자동화
- mysql
- node.js
- paging
- node
- MotionLayout
- Android 13
- Kotlin
- google play
- SWIFTUI
- PagingLib
- Reactive
- Android
- SwiftUI Tutorial
- liveData
- databinding
- 동영상
- GCP
- RxKotlin
- Animation
- list
- junit
- MediaSession
- mvvm
- MediaPlayer
- Observable
- android13
- 인앱결제
- Today
- Total
봄날은 갔다. 이제 그 정신으로 공부하자
android 개발자를 위한 Dispatch Group 본문
앞선 글(https://als2019.tistory.com/123)에서 설명한 것 처럼 iOS는 비동기 환경에서 실행된 다수 개의 Task 처리 완료 시 결과를 받아 처리할 수 있는 Dispatch Group을 지원합니다.
android는 Dispatch Group을 지원하지 않지만 @Synchronized를 사용하면 iOS의 Dispatch Group과 동일하게 사용할 수 있습니다.
이글에서는 android 개발자를 위한 Dispatch Group에 대해 설명하도록 하겠습니다.
아래와 같이 두개의 Network API를 호출하고 비동기로 결과를 받는 코드가 있다고 가정해보겠습니다.
MyNetworkModel.getList(offset: 0, limit: 20){ result ->
// 작업할 내용
}
MyNetworkModel.getInfo(myInfo: userId){ result ->
// 작업할 내용
}
저는 여기서 두개의 결과를 모두 받고 이후 처리를 하고자 합니다.
그럴 경우 간단하게 아래와 같이 코드를 추가할 수 있습니다.
var remainCount by MySynchronize(0)
MyNetworkModel.getList(offset: 0, limit: 20){ result ->
// 작업할 내용
remainCount -= 1
if (remainCount == 0) {
// 완료 후 처리할 작업
}
}
MyNetworkModel.getInfo(myInfo: userId){ result ->
// 작업할 내용
remainCount -= 1
if (remainCount == 0) {
// 완료 후 처리할 작업
}
}
위 코드는 왠지 부담스러워 보입니다.
그 이유는 어떤 Task가 작업 완료 Task인지 알 수 없어 모든 Task에 완료 여부를 체크하는 코드가 들어가기 때문입니다.
iOS에서는 멀티 Task 환경에서 작업 완료를 체크하는 Dispatch Group을 지원해 이를 사용해 Group에 속한 모든 작업의 완료를 확인 할 수 있는데 하는데 android에서는 이를 지원하지 않습니다.
얼핏 생각하기로 코루틴을 사용해서 해결하면 되지 않나라고 생각할 수 있지만 앞서 언급한 것과 같이 Network 호출 결과를 비동기로 받는 것이기 때문에 코루틴을 사용해서 해결하기가 곤란한 문제입니다.
이 문제를 해결하기 위해 위 코드에 사용한 var remainCount by MySynchronize(0)를 iOS의 Dispatch Group으로 아래와 같이 확장하도록 하겠습니다.
class DispatchGroup {
private var count = 0
private var runnable: (() -> Unit)? = null
init {
count = 0
}
@Synchronized
fun enter() {
count++
}
@Synchronized
fun leave() {
count--
notifyGroup()
}
fun notify(r: () -> Unit) {
runnable = r
notifyGroup()
}
private fun notifyGroup() {
if (count <= 0 && runnable != null) {
runnable!!()
}
}
}
이제 DispatchGroup을 아래와 같이 사용하면 됩니다.
val group = DispatchGroup()
group.enter()
MyNetworkModel.getList(offset: 0, limit: 20){ result ->
// 작업할 내용
group.leave()
}
group.enter()
MyNetworkModel.getInfo(myInfo: userId){ result ->
// 작업할 내용
group.leave()
}
group.notify {
// 완료 후 처리할 작업
}
이제 코드가 깔끔해지고 제 마음도 편안해졌습니다.
'android Tip' 카테고리의 다른 글
가볍게 보는 Singleton Pattern (kotlin & swift) (1) | 2022.12.05 |
---|---|
Splash Screen이란? (0) | 2022.02.16 |
잘되던 카톡 공유하기가 안된다면? (0) | 2021.12.27 |
아이콘 클릭 시 종처럼 흔들리는 애니메이션 효과 주기 (0) | 2021.04.07 |
android Bitmap과 함께하는 즐거운 시간 3번째 (0) | 2021.03.24 |