GDSC Sookmyung 활동/10 min Seminar

XML과 Compose의 차이점

yeoncheong 2023. 2. 27. 03:27

주제 선정 이유

UI를 그리는 것에 굉장한 흥미를 가지고 있어 모바일 앱을 공부하는 와중에,

저번 학기에 Google Compose Camp에 캠핑지기로 참여하게 되면서 새롭게 UI를 그리는 방법을 알게 되었으며

기존의 방법보다 훨씬 간결하고 효율적으로 UI를 작성할 수 있는 방법을 알게 되어 소개하고 싶었고,

기존 방법과 새로운 방법의 차이점을 비교하여 보여주고 싶었습니다.

 

 

안드로이드에서 현재 사용하는 UI 적용 방식

안드로이드는 XML을 이용하여 안드로이드의 화면을 구성하는 요소인 View, 다른 말로 Widget을 그리는 방식입니다.

XML 파일의 예시

 

XML은 태그를 이용하여 객체를 정의하는 마크업 언어로, 부모 - 자식 관계가 있기 때문에 UI의 구조가 ViewGroup - View의 Tree 형태로 표현됩니다.

하지만 복잡한 UI 형태를 그릴수록 트리는 점점 넓고 깊어지는 형태를 갖추게 되어 가장 안쪽에 있는 위젯에 도달하기 까지 위에서부터 차례대로 찾아 내려가야하는 비효율적인 서치가 발생하고,

태그 안에 태그가 반복되면서 내가 원하는 UI의 코드를 찾기 힘들만큼 가독성이 좋지 않습니다.

또한 로직 코드와 UI가 완전히 분리되어 있어 UI를 사용하기 위해서는 XML과 Class를 왔다갔다 하며 살펴봐야하고,

UI 하나하나의 값을 갱신해주기 위하여 각 View의 id 값을 알고 있어야 해 XML과 Class 간의 의존성이 매우 높습니다.

 

 

차례대로 리소스 XML, Layout XML, Class

게다가 중복되는 UI가 있을 경우, 보일러 플레이트 코드를 없애기 위해 리소스 XML 파일을 만들게 되는데,

그렇게 되면 한 화면을 구성하는데 리소스 파일 + 리소스 파일을 적용하는 Layout XML 파일 + View의 동작을 구현할 로직 파일, 총 3개의 파일을 생성하게 되면서 파일의 개수가 기하급수적으로 늘어나게 됩니다.

실제로 저는 작년에 진행한 안드로이드 프로젝트에서 20개의 화면을 만들었는데, 이때 사용한 XML 파일이 리소스 파일을 합쳐 총 56개였습니다.

 

기술의 발전으로 점점 다이나믹한 화면을 구성하게 되면서 현재의 UI 구현 방식이 굉장히 비효율적이었고, 그래서 등장한 것이 바로 Android Jetpack Compose입니다.

 

Compose란 무엇인가

Compose는 안드로이드 네이티브 UI를 개발하기 위해 구글에서 새롭게 출시한 선언형 UI 도구 키트입니다.

기존의 Android의 XML 작성 방식은 "특정 상태에 따라 UI가 어떻게 보여질지(How)"에 대한 구현이라면

Jetpack Compose는 "특정 상태에 따라 UI가 무엇을 보여주면 되는지(What)"에 대한 구현입니다.

 

정말 간단한 예시를 들어보겠습니다.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val textView = findViewById<TextView>(R.id.textView)
        textView.text = "Start Jetpack Compose"
    }
}

XML로 UI를 그렸을 때

  • setContentView라는 메소드를 이용하여 layout 파일을 보여줌
  • findViewById라는 메소드를 이용하여 id를 이용해 XML에 그린 View를 찾아서 코드단을 연결
  • 그렇게 가져온 View의 텍스트를 변경하라고 명령

 

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { 
            Text(text = "Start Jetpack Compose")
        }
    }
}

Compose로 UI를 그렸을 때

  • 간단한 코드임에도 짧아진 길이
  • 코드 상에서 이러한 Text를 그린다고 선언

 

플러터의 UI 구현

플러터를 해보신 분들이라면 느끼시겠지만 플러터의 UI 구현과 굉장히 비슷한 형태입니다.

플러터도 필요한 UI를 코드단에서 직접 선언하여 UI가 현재 어떤 상태인지만 그려주고, 이 UI를 구현하는 방식은 프레임워크에 맡기는 것입니다.

 

Compose의 장점은 안드로이드 공식 홈페이지에서도 이렇게 나와있습니다.

https://developer.android.com/jetpack/compose/why-adopt?hl=ko

코드 감소 적은 수의 코드로 더 많은 작업을 하고 전체 버그 클래스를 방지할 수 있으므로 코드가 간단하며 유지 관리하기 쉽다.
직관적 UI만 설명하면 나머지는 Compose에서 처리하며 또한 앱 상태가 변경되면 UI가 자동으로 업데이트 된다.
빠른 개발 과정 기존의 모든 코드와 호환되며 또한 실시간 미리보기 등 각종 안드로이드 스튜디오의 지원으로 빠르게 개발할 수 있다.
강력한 성능 안드로이드 플랫폼 API에 직접 액세스하고 머티리얼 디자인, 어두운 모드, 애니메이션 등을 기본적으로 지원한다.

Compose는 더 적은 수의 코드, 강력한 도구, 직관적인 Kotlin API로 Android에서의 UI 개발을 간소화하고 가속화하여 앱에 생동감을 더해주어 Android UI를 더 빠르고 쉽게 빌드할 수 있습니다. 안드로이드 공식이 열심히 밀어주고 있는 라이브러리 중 하나니 정말 효율적이겠죠?

 

명령형 UI와 선언형 UI

위에서 설명할 때 제가 명령이랑 선언이란 말을 했는데, 안드로이드의 UI를 그리는 방식은 크게 두 가지로 나뉘게 됩니다.

명령형 UI

  • View 따로 로직 따로
  • View 보고 너는 이렇게 동작해야한다고 명령
  • findviewbyid()와 같은 함수를 이용해서 트리를 탐색하고 메소드를 연결연결하여 객체한테 이렇게 갱신하라고 명령을 내리고 내부 상태 변경
  • 기존 명령형 UI 제작 방식은 개발자가 직접 set,get를 사용해야해서 내부 동작까지 모든걸 만들어야하는 과정이 있고 사람이 직접 로직을 만듦

-> 뷰가 많아질수록 내가 어떤 뷰를 연결했는지 헷갈리게 되면서 그 사이에서 실수들이 여럿 발생하여 버그 및 불필요한 작업 시간이 매우 소요됩니다.

 

b.setColor(red)
b.clearChildren()
ViewC c3 = new ViewC(...)
b.add(c3)

명령형 UI 시나리오

  • 어떤 변수를 참조하는 UI가 있다.
  • 이벤트에 의해 변수가 변경되었고 UI에 반영해야한다.
  • 명령형UI 프로그래밍 방식은 변경된 내용을 갱신할 것을 UI 객체에 명령한다.

 

선언형 UI

  • state라는 개념을 이용하여 값이 변경되면, 변경되어야 할 UI만 화면이 업데이트되도록
  • 코드단에서 이렇게 만들거야! 하고 선언 -> 굉장히 직관적
  • Compose의 선언형 접근 방식에서 위젯은 비교적 Stateless(상태 변화가 없는) 상태이며 명령형 UI와 달리 setter 또는 getter 함수를 노출하지 않음 -> 추상화가 잘 되어있음

-> Compose는 불필요한 보일러플레이트 코드가 줄어들어 버그가 일어날 확률도 줄고 적은 코드로 UI 구현이 가능해서 생산성이 빨라지고 유지보수하기 쉽습니다.

-> 또한, UI 전부를 갱신할 필요가 없기 때문에 효율성 측면에서도 아주 좋습니다.

 

return ViewB(
  color: red,
  child: ViewC(...),
)

선언형 UI 시나리오

  • 어떤 변수를 참조하는 UI가 있다.
  • 이벤트에 의해 변수가 변경되었고 UI에 반영해야한다.
  • 이벤트에 의해 변수를 변경해주면 해당 변수를 참조하고 있는 뷰는 State의 변경에 따라 뷰를 재생성한다.
  • 선언형UI는 명령형UI와는 달리 변화가 생긴 UI객체를 다시 생성한다. 

'GDSC Sookmyung 활동 > 10 min Seminar' 카테고리의 다른 글

MVC vs MVVM  (0) 2023.02.27
JWT란 무엇인가  (0) 2023.02.27
Spring Security Trivia  (0) 2023.02.21
메타버스 보안 기술  (0) 2023.02.20
알고리즘 초보의 공부법  (0) 2023.02.19