[Android] SAA with Jetpack Compose 적용기

[Android] SAA with Jetpack Compose 적용기
Android!

실제로 과거에 프로젝트에 적용했던 나의 경험을 바탕으로 한 글이다. 겪은 것에 대해 많은 것을 전달하려다보니 조금 더 자세하게 작성하려고 하여 깔끔하지 못한 점 양해 부탁한다.

SAA (Single Activity Architecture)

One Activity, Multiple Fragment
SAA structure

Single Activity Architecture(이하 SAA), 말 그대로 하나의 Activity로 이루어진 아키텍쳐이다. Multiple Activity를 바탕으로 여러 화면을 관리하는 방식이 일반적이지만, SAA는 앱 전체를 하나의 Activity로 구성하고, 그 안에 Fragment를 사용해 각 화면을 전환하는 방식이다. 해당 구조에서 핵심이 되는 것은 Jetpack Navigation Component이다.

2018년 Google I/O에서 SAA가 본격적으로 주목받기 시작했다. Google은 이때 Jetpack Library를 소개하면서 Navigation Component를 포함한 여러 도구들을 발표했는데, 이 컴포넌트는 하나의 액티비티 내에서 여러 화면을 전환하고 관리하는 아키텍처를 장려하였는데, 이것이 SAA이다. 이를 통해 코드 구조가 단순해지고, Activity와 Fragment 간의 복잡한 상호작용이나 생명 주기 관리가 용이해졌다.

SAA + Jetpack Compose

One Activity, Multiple Screen (Composable Function)
SAA + Compose structure

원래 SAA는 Single Activity, Multiple Fragment가 일반적이었다. 하지만, Google이 Jetpack Compose를 2019년 Google I/O에서 처음 발표하고 2021년 7월에 Jetpack Compose 1.0 버전을 정식 출시한 이후 본격적으로 다양한 곳에서 전환할 수 있게 되었다. 그러면서 SAA + Jetpack Compose의 조합이 더욱 주목받게 된다. Fragment 대신 Composable Function으로 화면을 구성하여 Single Activity 구조에서 네비게이션을 관리하는 방식이 점차 표준화되고 있다. 해당 조합으로 Fragment를 사용하여 생기는 여러 문제(러닝 커브, 복잡한 생명 주기 관리 등)를 해결할 수 있다.

Jetpack Compose에서는 여러가지의 Composable Function이 조합되어 화면을 구성한다. 이렇게 구성된 하나의 화면을 우리는 Screen이라고 부르기로 했다. 이를 Atom, Component 등으로 구분하여 중복되어 여러 화면에 사용되는 요소들은 코드를 단일화하여 작성할 수 있도록 한다.

실제 프로젝트 적용기

프리랜서 생활을 하며 여러 고민 끝에 실제 서비스에 적용한 경험이 있다. 당시에 자료가 생각보다 많지 않았기 때문에 경험들을 바탕으로 어떤 구조가 좋을까 수많은 고민을 하고 수정하였고 해당 글이 그 결과이다. 아직 해결하고 싶은 부분들이 여럿 있지만 프로젝트를 마무리한 지금 시점에서 생각해보면 후회하지 않는다.

왜 해당 구조를 택했을까?

  1. 서비스 구조 상 Main Screen이 Bottom Navigation Bar를 중심으로 한 디자인이었다. 이 때문에 여러 Fragment를 활용해야 했는데 이럴거면 전체를 Jetpack Navigation 라이브러리를 이용해서 전환하면 되지 않을까? 라는 생각이 있었다.
  2. 그동안 나는 쭉 MVVM 패턴을 사용하고 있었다. 일관된 Depth에서 서로 상태를 공유하기 위해서는 ViewModel을 통째로 공유하는 것이 좋을 것 같았다.
  3. 서비스 특성 상 MVP에서 시작하여 규모가 점점 커질텐데 앱 규모가 어느정도로 커질지 명확하지 않아 구조를 빠르게 파악할 수 있어야 했고 유지보수하기에도 편리해야 했다.
  4. 3번의 이유에 이어 추후 Activity가 많아지게 되면 앱 자체가 무거워질텐데 성능과 동기/비동기 처리가 중요했던 서비스이기 때문에 최대한 가볍게 구성해야 했다.
  5. 난이도 측면에서도 어렵지 않을 것이라 판단했다. 기존에 Compose UI를 많이 활용해봐서 익숙했고 Fragment를 사용하지 않고 Composable 함수를 사용하기 때문에 Activity를 여러 개 사용하는 것과 크게 다르지 않을 것이라 판단했다.

프로젝트 구조

SAA + Compose Folder Structure

사용한 스택 및 라이브러리

  • Architecture
    • SAA (Single Activity Architecture)
    • MVVM
  • UI
    • Jetpack Compose
    • Navigation Compose
  • DI
    • Hilt
    • Dagger
  • Network
    • Retrofit2
    • okHttp
  • Logging
    • Timber
    • Firebase
  • DB
    • Room

좋았던 점

  1. 상태 공유 및 데이터 관리가 굉장히 편리하다. 최소화된 각 Activity 안에서는 ViewModel을 공유할 수 있으니 여러 Fragment 및 Composable 함수에서 쉽게 상태를 공유할 수 있게 된다. 복잡한 데이터 형식을 공유해야 할 수록 해당 장점이 극대화된다. 참고로 나는 해당 프로젝트에서 총 3개의 Activity를 사용하였다.
  2. 유지보수 및 코드를 이해하는데 걸리는 시간이 매우 단축되었다. 프리랜서 특성 상 나의 코드를 추후 다른 사람이 보고 수정해야 하는 상황이 생길 수 있다. 해당 과정에서 다른 개발자가 나의 코드를 보고 이해하는데 어려움을 겪는다면 이는 굉장히 큰 손실이 될 것이다. 또한, 이해한 이후에도 유지보수하는데 시간이 오래 걸리게 될 수 있는데 Navigation 개념 자체가 워낙 직관적이므로 이해하기가 굉장히 쉽다.
  3. 생명 주기를 관리하는데 문제가 생길 가능성이 많이 적어진다. 기존 다중 Activity 구조에서는 각 액티비티의 생명 주기가 달라 상태 유지에 어려움을 겪어왔었다. 예기치 못한 문제가 생기는 경우도 여럿 있었다. 하지만 SAA는 이런 문제를 줄여 준다.
  4. 기존에 쌓여있던 화면들에 대한 처리가 쉬웠다. navigate를 하는 과정에서 기존에 쌓여있는 Screen History를 자유롭게 왔다갔다 할 수 있다는 점이 편했다.
  5. 프로젝트 구조가 굉장히 깔끔해진다. 먼저, Jetpack Compose를 사용해 xml 파일을 따로 만들 필요가 없다. 그리고 기존에는 Activity와 Fragment를 혼재해서 사용하는 과정에 폴더 구조를 어떻게 해야 할지 고민이 되는 경우가 많았는데 SAA를 도입한 이후 MVVM에 부합하는 폴더 구조를 만들기 편리하였다.

어려웠던 점

  1. 내가 해당 구조를 택한 가장 큰 이유인 상태 공유 및 데이터 관리를 하는 과정에서 최소한의 Activity를 두고 ViewModel 자체를 공유하는 방식을 택하였다. 해당 과정에서 DI에 어려움을 겪었다. 추후 서술할 어려웠던 점 중 하나인 자료가 얼마 없다는 세번째 단점에서 이어지는 점이다.
  2. Navigation 방식만을 사용하다 보니 Depth 별로 중첩하여 사용해야 하는 경우가 생기는데 NestedNavigation 구조가 굉장히 헷갈린다. 나는 따로 문서를 작성하지 않았는데 전체적인 Navigation 구조가 어떻게 되는지 한눈에 볼 수 있는 문서가 있으면 좋을 것 같다. 이와 관련해서는 글을 추가로 하나 작성할 예정이다.
  3. SAA를 XML 프로젝트에 적용한 사례는 꽤 많았는데 Jetpack Compose 프로젝트에 적용한 사례는 거의 없어서 이를 직접 적용시키는데 많은 시간을 투자해야 했다. 지금은 그래도 찾으면 꽤 나오는 것으로 보인다.

마치며

나는 새로운 기술 및 스택을 적용하는 것에 열려있는 편이다. 그리고 재미있어 한다. SAA도 그렇게 시작했으나 막상 사용하다보니 굉장히 편리했다. 처음에 구조 잡는게 어렵긴 하지만 한 번 익숙해지면 빠져나가기 어렵지 않을까 싶다. 앞으로 더 효율적인 구조가 없을까 고민은 계속 해볼 예정이다. Github에 SAA + Compose 예제 프로젝트 또한 올려볼 생각도 있다.

프로젝트 진행 특성 상 매번 똑같은 개발을 진행하는데에 익숙해지면 지치기 마련이다. 그럴 때 새로운 프로젝트 준비 과정에서 이런 기술을 적용해본다면 활기를 불어넣을 수 있을 것이다. 나는 지금까지 그래왔고 꽤 효과적이었다.

Park Sang-uk

Park Sang-uk

South Korea