ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Android] 팀 프로젝트 Splash Activity 버그 개선기 feat. ViewTreeObserver
    Android📱/삽질 기록... 2022. 9. 27. 14:54

    너무 간단한 문제였는데...

    너무 헤매어서

    기뻐서 기록을 남겨보려 합니다....

     

    얼마 전에 진행한 집 넘기기 프로젝트에서 겪었던 문제가 있었다.

    바로 Splash Activity....

     

    문제 발생

     

    자동 로그인 로직을 수행하기 위해서

    시작 시 isLogin이라는 내부저장소에 있는 변수를 검사할 필요가 있었고, 이를 수행하기 위해서 Splash Activity를 이용하여 Splash Screen을 띄워서 화면을 잠시 가리고 로직을 수행하고 어플을 시작하려고 하였다.

     

    다행히 의도대로 작동되는 듯하였으나

    Slpash Screen이 사라지고 HomeActivity로 이동하는 것이 아니라, 하얀 화면만 뜨는 현상이 발생

     

    이처럼 정체 모를 화면이 뜬 채로 멈춰있다가

    다시 들어오면 HomeActivity로 이동하는 현상이 발생했다.

     

    상황 파악

    일단 재현을 해보며 왜 이런 문제가 발생하는지 판단해보기로 했다.

     

    Splash Activity와 HomeActivity의 생명주기 별로 로그를 찍어보았다.

    그 결과 저 하얀 화면은 Splash Activity로 판명!

     

    저 당시 로직은 Splash Activity에서 viewModel를 갖고 있고,

    viewModel은 DataStore에 있는 isLogin을 가져와서 true인지 false인지 판단을 해서 로그인을 했는지 안 했는지 파악을 하고,

    로그인이 되어있으면 Home, 아니면 Login 액티비티로 이동을 하는 로직이다.

     

    요약

    Splash Screen -> viewModel 초기화 -> DataStore의 isLogin 가져오기 -> if(isLogin == true){ HomeActivity  } else { LoginActivity }

     

    DataStore에서 flow로 끌고 온 isLogin을 StateFlow로 보관하고 관찰했는데

    프로젝트를 진행 해면서 flow와 비동기에 많이 데어서 그런가 당연히 StateFlow를 관찰하는 부분에서 문제가 일어난다고 생각해서

    한참을 헤매다가 오늘 문제를 해결했다.

     

    문제 해결

     

    고민을 하다가 거의 포기 상태였는데

    오늘 불현듯 지나간 코드 바로 ViewTreeObserver!!

     

    isLogin을 관찰하는 코드가 ViewTreeObserver.OnPreDrawListener 안에 있었다.

    전에도 저 부분을 의심을 해서 저 부분을 밖으로 뺐다가 안으로 넣었다가 별걸 다했는데

    안되어서 신경 안 쓰고 있었는데

    오늘 불현듯 다시 눈에 밟히는 것이다.

     

    그래서 ViewTreeObserver를 찾아보고 OnGlobalLayoutListener로 바꿔서 적용을 해보았다.

     

    그리고 로그를 봤는데....

    onRestart를 하고 onResume이 될 때 isLogin을 collect 하는 것을 확인했다.

    원래는 onPause일 때 collect였는데

    로그를 확인하니 이제 viewTreeObserver가 이해가 되었다.

     

    원래 사용하던 OnPreDrawListener는 onPause가 되어서 뷰를 그리기 전의 상태가 될 때 isLogin을 콜렉트 하게 되는데

    viewModel이 초기화되고 isLogin을 받아올 때쯤이면 이미 뷰가 그려진 후라서 콜렉트가 안 되는 것이었다.

     

    그래서 제한 시간이 있는 스플레시 스크린은 사라지고 스플래시 액티비티만 덩그러니 남아있다가 백버튼을 하거나 여러 이유로 onPause가 되면 콜렉트 되어 HomeActivity가 켜지는 것이었다....

    그리고 OnGlobalLayoutListener는 뷰트리의 상태가 바뀌거나 가시성이 변경되고 난 후 작동을 하는 리스너라서 홈버튼을 눌렀다가 들어오면 HomeActivity로 가는 것이었다....

     

    사실 처음에 찾아봤을 때는 뭐가 그리기 전에 한다는 건지 뭘 그러고 나서 한다는 건지 이해를 못 했는데

    이번 기회로 이해가 된듯하다.

     

    그래서 결론적으로 viewTreeObserver 제거하니 잘 됨...

     

    Splash Activity 쓴다고 ViewTreeObserver를 항상 써야 하는 것은 아니더라....

     

     

     

     

Designed by Tistory.