JEP's Diary

Compose 이해 본문

Development/Android

Compose 이해

지으니88 2022. 11. 2. 21:00

Compose는 네이티브 Android UI를 위한 최신 선언형 UI 도구 키트이다. 더 짧은 코드, 강력한 도구, 직관적인 Kotlin API로 네이티브 UI개발을 간소화하고 가속화한다.

 

선언형 프로그래밍 패러다임

이전의 Android 뷰 계측 구조는 UI 위젯의 트리로 표시했다. findViewById() 로 트리를 탐색하고, button.setText("")과 같은 함수 호출로 UI를 업데이트 했다.

선언적 UI ahepfdms 화면전체를 개념적으로 재생성한 후 필요한 변경사항만 적용하는 방식으로 작동한다. 이것은 스테이트풀(Sateful) 뷰 계측 구조를 수동으로 업데이트할때의 복잡성을 방지할 수 있다. 화면 전체를 재생성할 때 비용이 많지 들지만, 이 비용을 줄이기 위해 Compose는 특정 시점에 UI의 어떤 부붐을 다시 그려야 하는지 지능적으로 선택한다. 이 부분이 UI 구성요소를 디자인하는 방식에 몇가지 영향을 미친다.

 

간단한 구성 가능한 함수 Composable

데이터를 받아서 UI 요소를 내보내는 Composable 함수 집합을 정의하여 화면을 구성한다.

@Composable
fun Greeting(name: String) {
	Text("Hello Android")
}

그림1
그림2

그림1에 대한 설명

앱 로직은 최상위의 Composable 함수에 데이터를 제공한다. 최상위 Composable 함수에서는 해당 데이터를 사용하고 필요에 따라 계층 구조 아래(다른 Composable 함수)로 전달한다. 사용자가 UI와 상호작용을 하여 onClick 과 같은 이벤트가 발생했을때는 이러한 이벤트를 앱 로직에 전달하여 State를 변경하고, 이 State를 사용하고 있는 Composable 함수들은 State가 변경되었으니 새 데이터와 함께 다시 호출되어 재구성이 된다.

 

그림2에 대한 설명

사용자가 UI 요소와 상호작용하여 onClick 이벤트가 트리거 된다. 앱 로직이 이벤트에 응답한다. 그러면 Composable 함수가 필요한 경우 새 매개변수를 사용하여 자동으로 다시 호출된다. (그림1의 후반부 설명과 중복되어있음)

 

동적 컨텐츠

Kotlin 코드로 작성되므로 동적일 수 있다.

 

재구성

명령형 UI에서의 위젯 변경하려면 위젯의 setter를 호출(button.setText)하여 상태를 변경했다. Compose에서는 새 데이터를 사용하여 Composable 함수를 다시 호출한다. 이것을 재구성 한다라고 표현한다. 이때 변경된 구성요소만 재구성 한다는 장점이 있다.

주의사항

  • Composable 함수에서 SharedPreference에 읽거나 쓰지 않는다. -> 읽고 쓰는 로직은 ViewModel에서.
  • ViewModel에서 식별 가능한 요소 업데이트는 부작용이 있다. (이 말은 뭘까..?이해못함 22.11.02)
  • Composable 함수 전역변수에 접근하면 부작용이 있다.

재구성의 관련하여 Compose에서 프로그래밍 할 때 알아야할 사항

  • Composable 함수는 순서와 관계없이 실행할 수 있음
    아래의 Composable 함수들은 반드시 순서대로 실행되지는 않으며 순서와 관계 없이 실행될 수 있다.

 

@Composable
fun ButtonRow() {
    MyFancyNavigation {
        StartScreen() // Composable 함수
        MiddleScreen() // Composable 함수
        EndScreen() // Composable 함수
    }
}

 

  • 구성 가능한 함수는 동시에 실행할 수 있음
    Compose는 Composable 함수를 동시에 실행하여 재구성을 최적화 할 수 있다. 이것은 Composable 함수가 백그라운드 스레드 풀 내에서 실행 될 수 있다는 것을 의미한다. ViewModel에서 Composabl 함수를 호출하면 동시에 여러 스레드에서 이 함수를 호출할 수 있다. 대신에 올바르게 작동되는 것을 기대한다면 모든 Composable 함수에 부작용이 없어야한다. 또 구성 가능한 람다의 변수를 수정하는 코드는 피해야 한다. (아래코드)
@Composable
@Deprecated("Example with bug")
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")
    }
}
  • 재구성은 가능한 한 많이 건너뜀
    Compose는 업데이트 해야 하는 부분만 재구성한다.
  • 재구성은 낙관적임
    재구성이 완료되기 전에 매개변수가 변경되면 Compose는 재구성을 취소하고 새 매개변수를 사용하여 재구성을 다시 시작할 수 있다.
  • 구성 가능한 함수는 매우 자주 실행될 수 있음
    경우에 따라서 Composable 함수는 UI 애니메이션의 모든 프레임에서 실행 될 수 있다. 함수가 비용이 드는 작업을 실행하면 UI버벅거림이 발생할 수 있다. 때문에 비용이 많이 드는 작업은 다른 스레드로 이동하고 mutableStateOf/LiveData를 사용하여 데이터를 전달해야한다.

'Development > Android' 카테고리의 다른 글

Compose 기본사항 키워드 정리  (0) 2022.11.15
Android Webview의 Bridge를 대신할 WebMessagePort  (0) 2022.11.02
Compose Camp 시작!  (0) 2022.11.02
ViewPager2  (0) 2021.01.06
Android ViewModel  (0) 2018.08.08