선생님, 개발을 잘하고 싶어요.

[아틱 프로젝트] 스플래쉬 화면의 구현, rxjava, combineLatest 본문

개발/android 개발

[아틱 프로젝트] 스플래쉬 화면의 구현, rxjava, combineLatest

알고싶은 승민 2019. 8. 5. 02:44

상황

1. Splash Activity가 Lottie를 이용한 스플래시 애니메이션을 실행해 주어야 한다.

2. Splash Activity가 자동 로그인 성공하면 Main Activity로, 실패하면 Login Activity로 분기 해야 한다.

문제

자동 로그인 결과가 나오자마자 분기하면 스플래시 애니메이션이 중간에 끊긴다.

 

반대로 스플래시 에니메이션이 끝나고 분기하면 자동 로그인의 성공여부를 몰라 어디로 분기해야 할지 알 수가 없다.

해결책

rxjava의 combineLatest를 사용해서 두개의 비동기 작업을 연결한다.

 

// 애니메이션이 끝날 때 animationEnd 스트림에 종료를 알린다.
lottie_splash.addAnimatorListener(
    object : Animator.AnimatorListener {
        override fun onAnimationRepeat(animation: Animator?) { }

        override fun onAnimationEnd(animation: Animator?) {
            animationEnd.onNext(true)
        }

        override fun onAnimationCancel(animation: Animator?) { }

        override fun onAnimationStart(animation: Animator?) { }
    }
)

// 자동로그인이 끝날 때 autoLogin 스트림에 로그인 성공 여부를 알린다.
auth.autoLogin()
    .subscribe { success -> 
        autoLoginEnd.onNext(success)
    }

// 적어도 스플래쉬 화면이 한 번의 애니메이션을 실행해야한다.
// 스플래쉬 화면에서 자동 로그인을 요청해야 한다. 그리고 요청 결과에 따라 다음 화면으로 이동해야 한다.

// 애니메이션이 끝나고 자동 로그인이 끝나면 방출하는 Observable 을 combineLatest를 사용해서 구성했다.
Observable.combineLatest(
    animationEnd, autoLoginEnd, BiFunction<Boolean, Boolean, Boolean> { _, loginSuccess
        -> loginSuccess
    }
).subscribe {
    if (it) {
        // 자동 로그인이 성공되면 Main 화면으로 이동하자!
        startActivity(intentFor<MainActivity>())
    }
    else {
        // 자동 로그인이 실패되면 LoginActivity 화면으로 이동하자!
        startActivity(intentFor<LoginActivity>())
    }
}

 

결론

여러가지 작업을 스트림처럼 생각하고 rxjava의 operator를 사용하면 작업들을 유연하게 연결하고, 결합해서 프로그래밍 할 수 있다.

Comments