반응형
여태까지 개발을 모바일앱 개발을 하면서 특정 타이밍 때문에 delay를 별도로 준적이 많다.
예제로 사용할 앱 첫로딩시에 첫번째 fragment statck을 가져와야할때가 예시라고 할수있다.
그럴때마다 delay를 별도로 줘서 데이터를 가져왔다.
lifecycleScope.launch {
delay(700)
val current = navHostFragment.childFragmentManager.fragments.firstOrNull()
}
저렇게 딜레이를 주지 않으면 앱이 시작할때나 특정타이밍에 null인 케이스가 종종 발생한다.
이렇게 딜레이를 주고 값을 받아오는건 좋지 않은 코드이다. 불필요하게 기다릴수도 또는 저 타이밍안에 못들어올수도 있으니,
해당부분과 같은 비동기처리를 하는방법중 하나는 아래와 같다.
private suspend fun waitFirstFragment(navHostFragment: Fragment): Fragment {
return suspendCancellableCoroutine { continuation ->
val fragmentManager = navHostFragment.childFragmentManager
val existingFragment = fragmentManager.fragments.firstOrNull()
if (existingFragment != null) { //프래그먼트가 null인지 체크하여 null이 아니면 fragment를 전달
continuation.resume(existingFragment)
} else {
//없다면 fragment callback을 추가하여 데이터를 전달받음
val callback = object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentAttached(
fm: FragmentManager,
fragment: Fragment,
context: Context
) {
fragmentManager.unregisterFragmentLifecycleCallbacks(this)
continuation.resume(fragment)
}
}
//전달받을때까지 기다릴수 있도록 처리
fragmentManager.registerFragmentLifecycleCallbacks(callback, true)
continuation.invokeOnCancellation { //완료되면 콜백 제거
fragmentManager.unregisterFragmentLifecycleCallbacks(callback)
}
}
}
}
위의 코드가 callback으로 결과값을 받을수있는 형식이다
suspendCancellableCoroutine을 이용한다면 아주 쉽게 비동기처리를 해결할수있다.
continuation.resume(existingFragment)
데이터의 값을 전달하는건 resume으로 데이터를 전달 해야한다.
그리고 위의 예제와 같이 필수적으로 완료된 후 처리를 해야하는 무엇인가가 있다면 invokeOnCancellation을 이용해서 처리해야한다.
해당 예제는 callback을 제거해야 하기에 invokeOnCancellation 를 이용하였다.
continuation.invokeOnCancellation { //완료되면 콜백 제거
fragmentManager.unregisterFragmentLifecycleCallbacks(callback)
}
반응형
'프로그램 > Android' 카테고리의 다른 글
구글스토어 다국어 스토어설정 (1) | 2024.10.07 |
---|---|
캠월드 개발일지 2(디자인가이드 적용) (0) | 2024.09.24 |
안드로이드 구글로그인 기능 (1) | 2024.09.19 |
[캠월드] 캠월드 개발일지 1(멀티모듈 적용) (1) | 2024.09.12 |
안드로이드 google-services.json을 여러개 사용하기 (0) | 2022.02.21 |