JetPack Compose
JetPack Compose는 안드로이드 앱의 UI를 쉽게 디자인하고 빌드하기 위한 라이브러리이다.
Compose가 만들어진 목표는 다음과 같다.
- 맞춤 레이아웃을 쉽게 작성
- 고성능 발휘
📌 맞춤 레이아웃을 쉽게 작성
기존 안드로이드에서는 xml로 View를 그려주고, 코드상에서 setContentView나 inflate 메소드를 이용해 해당 View를 로드해야 했다.
JetPack Compose를 이용하면 이전과 달리 Compose에서는 코드 상에서 UI에 대한 모든 관리를 하게 된다.
이로 인해 View가 작성되기 쉬워지게 된다.
물론 Binding Library를 사용하면 Parent View를 Binding해놓고 View를 찾는 과정 없이 바로 자식View에 대한 접근이 가능하기도 하지만, 큰 틀 자체는 바뀌지 않는다.
📌 고성능을 발휘
JetPack Compose에서는 Android에서 View를 그려줄 떄 생기는 성능상의 고질적인 문제를 해결하였다. 레이아웃 상의 하위 요소를 두 번 이상 측정해야하는 경우가 많은데, 이로 인해 성능이 부족한 핸드폰에서는 앱의 성능이 안 좋아지거나, 앱이 버벅거리는 문제가 발생되었다.
Compose는 이를 해결하기 위해 레이아웃 하위 요소를 두 번 이상 측정하는 것을 금지시키며, 여러 측정값이 필요할 경우 Compose상의 내장 측정 기능을 이용해 측정할 수 있도록 하였다.
예를 들어, 특정 Row의 사이즈를 Row가 가질 수 있는 가장 작은 Size로 만든다고 하자.
그 때 이러한 내장 측정 기능을 사용하여 크기를 계산할 수 있다.
📌 의의와 한계점
의의
위 두가지 기능만 보았을 때, JetPack Compose는 기존 방식에 비해 혁신적인 방식이다. xml을 읽어 View를 inflate하는 과정을 없앴고, 그려진 View에서 자식 View를 찾아 데이터를 세팅해주는 위치를 일원화했다. 또한 기존에 View의 크기를 계산하기 위해 동적으로 계산 로직이 들어가 성능 저하가 발생했던 문제점을 내장측정 기능을 이용해 해결하였다.
한계점
하지만 코드 상에서 View를 그려주고 데이터를 세팅하는 것을 하나로 합친 방식에는 한계점이 존재한다.
대표적으로 View코드와 데이터를 세팅하는 부분을 분리하지 못함으로써 View를 정의하는 계층과 View를 그려주는 계층 간 역할 분리가 제대로 되지 않는다는 문제점이 있다.
예를 들어,
MVVM구조에서 ViewModel에 View를 위한 데이터를 저장하고 있고, View에서 ViewModel의 데이터를 관찰하여 View의 데이터를 업데이트 시켰다.
이 과정에서,
View를 정의하는 계층(xml)과,
View를 그려주고 데이터를 세팅하는 Activity, Fragment가 분리되어 있었는데,
이제는 View 정의와 View 그려주는 역할을 모두 Activity, Fragment가 함으로써 Activity, Fragment에 더 많은 역할이 가게 되었다.
이러한 방식으로 코드를 작성하면 MVVM아키텍처를 제대로 이해하지 못했을 경우, 코드가 커질수록 UI코드와 데이터 간 결합도가 높아져 유지보수가 어렵게 된다.
이 부분을 JetPack Compose에서는 Stateless하게 @Composable
을 만들 수 있도록 함으로써 해결하고 있지만, 이해가 깊지 않은 사람들에게는 오히려 부작용으로 UI코드와 데이터의 결합도를 높이는 방안으로 활용될 수 있어 주의가 필요하다.
(이하 내용은 타 블로그 원문 및 공식문서를 보고 단순 필기한 내용입니다.)
State의 관점에서 본 Compose의 이해
기존 명령형 패러다임을 이용해 UI를 그릴 때의 한계점
- Stateful하다: View가 직접 State를 가지고 있는 것
ex)TextView는 text프로퍼티에 Kotlin World라는 State를 직접 가지고 있게 된다.
findViewById<TextView>(R.id.blog_title_text).text = "Kotlin World"
Stateful한 방식의 뷰 조작은 오류를 발생할 가능성을 높인다.
여러 위치에서 뷰에 들어가야 할 값을 setter를 이용해 업데이트할 경우, 데이터를 표시하는 부분 중 하나에 setter를 적용하는 것을 놓친다면 오류가 생기기 떄문이다.
명령형 프로그래밍 패러다임을 따르는 UI Kit는 Stateful하며,
뷰가 복잡해질수록 유지보수를 위한 복잡성이 증가된다.
Compose: 선언형 패러다임을 따라 Stateless하게 위젯을 생성
JetPack Compose는 Stateful했을 때의 문제를 해결하기 위해 등장하였다.
선언형 프로그래밍 패러다임을 따른다.
선언형 프로그래밍 패러다임?
선언형 프로그래밍은 어떤 방법으로 해야 하는지를 설명하는 것이 아닌, 어떠한 결과가 나와야 하는지를 나타내도록 프로그래밍하는 것을 뜻한다.
선언형 프로그래밍은 보통 DSL의 형태로 사용되는데, 대표적 언어로 SQL 등이 있다.
특정 테이블에 데이터를 넣기 위해 INSERT를 쓸 뿐, INSERT가 어떻게 수행되어야하는지 정의하지 않는다.
선언하면 DB가 알아서 Insert해준다.
마찬가지로 Compose에서는 위젯을 선언만 하면 위젯이 그려진다.
또한, Compose의 선언형 접근 방식에서는 위젯을 객체로 노출하지 않는다. (getter, setter함수를 직접 호출하지 않는다)
이로 인해 Compose가 그리는 위젯은 Stateless할 수 있다.
Compose가 그리는 위젯은 왜 Stateless할 수 있을까?
@Composable은 Compose로 그려지는 뷰를 뜻한다.
다음과 같이, state를 외부로부터 전달받을 뿐, 직접 가지고 있지 않다.
@Composable
fun blogTitle(blogName: String){
Row{
Text(blogName)
}
}
이러한 위젯 구성 방식을 우리는 Stateless하다고 한다.
선언형 패러다임으로의 전환의 의의
안드로이드의 MVVM 아키텍처는 ViewModel에서 State를 관리한다. Compose를 사용하면 모든 위젯을 Stateless하게 구성한 다음, ViewModel로부터 필요한 State를 전달받을 수 있게 된다. 이를 통해 기존 명령형 프로그래밍 패러다임에서 View가 복잡해질수록 유지보수를 위한 복잡성이 증가하는 것을 방지하고, State의 관리 포인트를 일원화함으로써 코드를 깔끔하고 유지보수하기 쉽게 유지할 수 있게 된다.
참고 링크
'App > Android' 카테고리의 다른 글
[Android][Kotlin] 3. JetPack Compose - 리스트(ListView, RecyclerView), LazyColumn (0) | 2022.09.19 |
---|---|
[Android][Kotlin] 2. JetPack Compose - @Composable, @Preview, Box (1) | 2022.09.19 |
[Android][Error] Parcel: unable to marshal value - ArrayList를 Intent에 담아 보내기 (0) | 2022.08.29 |
[Android][공부기록] Main Thread란?(+ 실습으로 알아보기) (0) | 2022.08.11 |
[Android][공부기록] MVP, MVVM패턴을 간단히 알아보자 (0) | 2022.07.23 |