[Compose UI] Jetpack Compose 이해하기

LeeEunJae·2022년 12월 23일
0

📌 Compose?

Jetpack Compose는 Android를 위한 현대적인 선언형 UI 도구 키트입니다. Compose는 프런트엔드 뷰를 명령형으로 변형하지 않고도 앱 UI를 렌더링할 수 있게 하는 선언형 API를 제공하여 앱 UI를 더 쉽게 작성하고 유지관리할 수 있도록 지원합니다

📌 선언/명령형 프로그래밍?

명령형 프로그래밍

지금까지 안드로이드 앱을 만들 때, xml 로 뷰를 구성하고, 앱의 상태가 변경되면(데이터가 변경되면), 코드상에서 findViewById() 또는 viewBinding 을 사용해서 UI 위젯의 트리를 탐색하고, UI를 업데이트 했었습니다.

위와 같은 방법으로 UI를 업데이트 했을 때 문제점

  • 뷰를 수동으로 조작하면 오류 발생 확률이 높다.
  • 데이터를 여러 위치에서 렌더링 한다면, 데이터를 표시하는 뷰 중 하나를 업데이트 하는 것을 잊기 십다.
  • 두 업데이트가 예기치 않은 방식으로 충돌 할 경우 잘못된 상태를 야기한다.
  • 소프트웨어 유지관리 복잡성이 증가한다.

선언형 프로그래밍

지난 몇 년에 걸쳐 업계 전반에서 선언형 UI 모델로 전환하기 시작했으며, 이에 따라 사용자 인터페이스 빌드 및 업데이트와 관련된 엔지니어링이 크게 간소화되었습니다. 이 기법은 처음부터 화면 전체를 개념적으로 재생성한 후 필요한 변경사항만 적용하는 방식으로 작동합니다. 이러한 접근 방식은 스테이트풀(Stateful) 뷰 계층 구조를 수동으로 업데이트할 때의 복잡성을 방지할 수 있습니다. Compose는 선언형 UI 프레임워크입니다.

화면 전체를 재생성하는 데 있어 한 가지 문제는 시간, 컴퓨팅 성능 및 배터리 사용량 측면에서 잠재적으로 비용이 많이 든다는 것입니다. 이 비용을 줄이기 위해 Compose는 특정 시점에 UI의 어떤 부분을 다시 그려야 하는지를 지능적으로 선택합니다. 이는 재구성에 설명된 대로 UI 구성요소를 디자인하는 방식에 몇 가지 영향을 미칩니다.

📌 Composable 함수


@Composable 어노테이션을 사용하고 함수를 정의 하면, 뷰를 그릴 수 있습니다.
기존에 xml 코드로 뷰를 그리던 것을 @Composable 함수로 만든다고 생각하면 됩니다.
@Composable 어노테이션을 사용하면, 이 함수가 데이터를 UI로 변환하기 위한 함수라는 것을 Compose 컴파일러에 알립니다.

📌 선언형 패러다임 전환

많은 명령형 객체 지향 UI 도구 키트를 사용하여 위젯의 트리를 인스턴스화함으로써 UI를 초기화합니다. 흔히 XML 레이아웃 파일을 확장하여 이 작업을 합니다. 각 위젯은 자체의 내부 상태를 유지하고 앱 로직이 위젯과 상호작용할 수 있도록 하는 getter 및 setter 메서드를 노출합니다.

Compose의 선언형 접근 방식에서 위젯은 비교적 스테이트리스(Stateless) 상태이며 setter 또는 getter 함수를 노출하지 않습니다. 사실상 위젯은 객체로 노출되지 않습니다. 동일한 구성 가능한 함수를 다른 인수로 호출하여 UI를 업데이트합니다. 이렇게 하면 ViewModel과 같은 아키텍처 패턴에 상태를 쉽게 제공할 수 있습니다. 그런 다음, 컴포저블은 식별 가능한 데이터가 업데이트될 때마다 현재 애플리케이션 상태를 UI로 변환합니다.

앱 로직은 최상위의 Composable 함수에 데이터를 제공합니다. 그러면 함수는 데이터를 사용하여 다른 Composable을 호출함으로써 UI를 형성하고 적절한 데이터를 해당 Composable 및 계층 구조 아래로 전달합니다.

사용자가 UI와 상호작용할 때 UI는 onClick과 같은 이벤트를 발생시킵니다. 이러한 이벤트를 앱 로직에 전달하여 앱의 상태를 변경해야 합니다. 상태가 변경되면 Composable 함수는 새 데이터와 함께 다시 호출됩니다. 이렇게 하면 UI 요소가 다시 그려집니다. 이 프로세스를 재구성(Recomposition)이라고 합니다.

📌 Recomposition

Compose에서는 새 데이터를 사용하여 Composable 함수를 다시 호출합니다. 이렇게 하면 함수가 recomposition 되고, 필요한 경우 함수에서 내보낸 위젯이 새 데이터로 다시 그려집니다. Compose 프레임워크는 변경된 구성요소만 지능적으로 recomposition 할 수 있습니다.

예를 들어 다음과 같이 버튼을 표시하는 구성 가능한 함수를 생각해 보세요.

@Composable
fun ClickCounter(clicks: Int, onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text("I've been clicked $clicks times")
    }
}

버튼이 클릭될 때마다 호출자는 clicks 값을 업데이트합니다.
Compose는 Text 함수를 사용해 람다를 다시 호출하여 새 값을 표시합니다.
이 프로세스를 recomposition이라고 합니다. 값에 종속되지 않은 다른 함수는 recomposition 되지 않습니다.

앞서 논의했듯이 전체 UI 트리를 재구성하는 작업은 컴퓨팅 성능 및 배터리 수명을 사용한다는 측면에서 컴퓨팅 비용이 많이 들 수 있습니다. Compose는 이 지능적 재구성을 통해 이 문제를 해결합니다. - Compose(선언형 프로그래밍)의 장점

recomposition은 입력이 변경될 때 Composable 함수를 다시 호출하는 프로세스입니다. 이는 함수의 입력이 변경될 때 발생합니다. Compose는 새 입력을 기반으로 재구성할 때 변경되었을 수 있는 함수 또는 람다만 호출하고 나머지는 건너뜁니다. 매개변수가 변경되지 않은 함수 또는 람다를 모두 건너뜀으로써 Compose의 재구성이 효율적으로 이루어질 수 있습니다.

📌 참고자료

안드로이드 공식 문서

profile
매일 조금씩이라도 성장하자

0개의 댓글