Jetpack Compose
Jetpack Compose는 안드로이드 앱의 UI를 쉽게 디자인하고 빌드하기 위한 라이브러리이다.
Compose가 만들어진 목표는 다음과 같다.
- 맞춤 레이아웃을 쉽게 작성
- 고성능을 발휘
맞춤 레이아웃을 쉽게 작성
기존 안드로이드에서 xml로 View를 그리고 코드 상에서 setContentView나 inflate 메서드를 이용해 해당 View 을 로드해야 했다. Jetpack Compose를 이용하면 이전과 달리 compose에서는 코드 상에서 UI에 대한 모든 관리를 하게 된다. 이로 인해 View가 작성되기 쉬워지게 된다.
기존 방식
예를 들어 textView에 동적으로 "Kotlin World Blog" 라는 텍스트를 출력하고 싶다고 해보자. 기존에는 다음과 같은 방식으로 출력이 가능했다.
1. layout 파일을 작성한다.
2. layout 파일을 inflate한다. 후 layout파일 내부의 TextView를 찾는다.
3. TextView에 "Kotlin World Blog"를 출력한다.
물론 Binding Library를 사용하면 Parent View를 Binding 해놓고 View를 찾는 과정 없이 바로 자식 View에 대한 접근이 가능하기도 하지만, 큰 틀 자체는 바뀌지 않는다.
보여주여야 하는 리소스의 출력과 View를 그려주는 부분을 합친 Jetpack Compose
Jetpack Compose를 이용하면 TextView를 코드 상에서 다음과 같이 그려주고 바로 텍스트의 출력이 가능해진다. 그림1에 비해 코드양이 획기적으로 줄어들었고, 더욱 직관적이어졌다.
*<그림1>의 코드에는 Constraint Layout 위에 TextView를 그려주는 과정이 있었지만, 해당 부분은 이 글의 범위를 넘어가니 나중에 다루도록 한다.
고성능을 발휘
뿐만 아니라 Jetpack Compose는 Android에서 View를 그려줄 때 생기는 성능상의 고질적인 문제를 해결하였다. 레이아웃 상의 하위 요소를 두 번 이상 측정해야 하는 경우가 많은데 이로 인해 성능이 부족한 휴대폰에서는 앱의 성능이 안좋아지거나, 앱이 버벅거리는 문제가 발생되었다. Compose는 이를 해결하기 위해 레이아웃 하위 요소를 두 번 이상 측정하는 것을 금지시키며 여러 측정값이 필요할 경우에는 Compose 상의 내장 측정 기능을 이용해 측정할 수 있도록 하였다.
예를 들어 특정 Row의 사이즈를 Row가 가질 수 있는 가장 작은 Size로 만든다고 하자. 이러한 내장 측정 기능을 사용하기 위해서 우리는 IntrinsicSize(고유크기) 라는 기능을 이용한다. 이 기능을 통해 내장 측정 기능을 사용하여 크기를 계산할 수 있다.
의의와 한계점
위의 두가지 기능만 보았을 때, Jetpack Compose는 기존 방식에 비해 혁신적인 방식이다. xml을 읽어 View를 inflate하는 과정을 없앴고, 그려진 View에서 자식 View를 찾아 데이터를 세팅해주는 위치를 일원화 하였다. 또한 기존에 View의 크기를 계산하기 위해 동적으로 계산 로직이 들어가 성능 저하가 발생했던 문제점을 내장측정 기능을 이용해 해결하였다.
하지만 코드 상에서 View를 그려주고 데이터를 세팅하는 것을 하나로 합친 방식이 Jetpack Compose에서 새롭게 시도되는 방식은 아니다. 윈도우 어플리케이션을 제작하는 Eclipse RCP를 비롯해 IOS 개발에서도 비슷한 방식이 채택되었었고, 이 방식에도 한계점이 존재하였다.
대표적으로는 View코드와 데이터를 세팅하는 부분을 분리하지 못함으로써 View를 정의하는 계층과 View를 그려주는 계층간에 역할 분리가 제대로 되지 않는다는 문제점이 있다.
Android MVVM구조에서는 ViewModel에서 View단을 위한 데이터를 저장하고 있고 View에서는 ViewModel의 데이터를 관찰하여 View의 데이터를 업데이트 시켰다. 이 과정에서 View를 정의한 계층인 xml과 View를 그려주고 데이터를 세팅하는 계층인 Activity, Fragment가 분리되어 있었는데, 이제는 View정의와 View를 그려주는 역할을 Activity, Fragment에서 모두 함으로써 Acitivty, Fragment에 많은 역할이 가게 되었다.
이러한 방식으로 코드를 작성하면, MVVM 아키텍처를 제대로 이해 하지 못하고 코드를 만들 경우, 코드가 커질수록 UI코드와 데이터간의 결합도가 높아져 유지보수가 어렵게 된다. 이 부분을 Jetpack Compose에서는 Stateless하게 @Composable을 만들 수 있도록 함으로써 해결하고 있지만, 이해가 깊지 않은 사람들에게는 오히려 부작용으로 UI코드와 데이터의 결합도를 높이는 방안으로 활용될 수 있어 주의가 필요하다.