Jetpack Compose와 Recomposition
on Android, Compose
Last modified at:
=======
Jetpack Compose와 Recomposition
선언형 UI 패러다임
기존 명령형 프로그래밍 방법으로 UI를 수정하는 방법은 setText
와 같이 명령어를 이용하여 업데이트하였다.
val textView = findViewById<TextView>(R.id.text_view)
textView.setText("hello")
textView.setTextColor(...)
...
이러한 방법은 데이터를 렌더링해야 할 위치가 여러 군데라면 누락하기도 쉽고 그만큼 오류 발생률이 올라간다. 또한 여러 군데에서 동시에 렌더링할 경우 충돌 발생 가능성이 있다.
선언형 프로그래밍 방법으로 UI를 수정할 경우에는 State를 UI로 변환하기 위한 선언적 코드만 있으면 된다. UI의 실제 구현은 프레임워크(Compose)가 담당한다.
MVVM의 ViewModel을 이용하여 Observable 데이터가 변경될 때마다 Composable 함수를 호출하는 구조를 만들기 용이하다. Observable 데이터를 파라미터로 넘겨 Compose 프레임워크가 data를 ui로 바꾸기 용이하다.
Compose 기본
@Composable
fun Greeting(name: String) {
Text("Hello $name")
}
Compose 사용 방법
@Composable
Annotation을 사용하여 함수를 Composable 함수로 만들 수 있다.- 매개변수를 받을 수 있다. 위의 예제에서는
name
string 값을 받는다. - Composable은 내부에 다른 Composable 함수를 호출한다. 예제에서는
Text
라는 Composable 함수를 호출한다. - 반환 값이 없다. 어떤 값을 반환하는 것이 아닌 함수의 내용이 원하는 화면의 상태를 설명한다.
- Composable 함수는 빠르고 멱등원이고 Side effect가 없다.
멱등원: 연산을 여러번 적용하여도 결과가 달라지지 않는 성질,
f(f(x)) = f(x)
- 동일한 인수로 여러번 호출할 때 동일한 방식으로 작동, 전역 변수나 랜덤과 같은 요소를 사용하지 않는다. - 속성 또는 전역 변수 수정과 같은 Side effect를 일으키지 않는다.Dynamic Contents
Composable 함수는 Kotlin으로 작성되기 때문에 동적으로 작성할 수 있다.
@Composable fun Greeting(names: List<String>) { for (name in names) { Text("Hello $name") } }
Recomposition
Compose는 Composable 함수를 다시 호출하는 방법으로 함수 내부의 상태를 변경할 수 있다. Recomposition은 다음과 같은 특징을 가진다.
- Composable은 순서와 관계없이 실행된다. Composable 함수 내에서 다른 Composable 함수 호출이 포함되어 있으면 순서와 관계없이 실행한다.
- 멀티 코어를 활용하여 동시에 실행할 수 있다. Recomposition이 일어날 때 thread-safety를 고려해야 한다.
@Composable fun ListWithBug(myList: List<String>) { var items = 0 Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Text("Item: $item") items++ // Avoid! Side-effect of the column recomposing. } } Text("Count: $items") } }
- Recomposition은 업데이트가 필요한 부분만 업데이트를 수행한다.
- Recomposition is optimistic. Compose는 인자가 다시 변경되기 전에 recomposition을 끝낸다는 뜻이다. 만약 recomposition이 끝나기 전에 인자가 변경되면 진행 중인 recomposition을 취소하고 새 인자로 다시 recomposition을 진행한다. Side-effect가 있을 경우 composition이 취소되더라도 side-effect는 적용된다.
- Composable 함수는 자주 실행될 수 있다. 초당 수백번 실행될 수도 있다. 저장소에서 데이터를 가져오는 동작 등이 함수 내에 있으면 동작이 느려질 수 있다(=버벅임)