— Compose는 XML의 대체제가 아니다
Android 개발을 오래 해온 사람이라면 자연스럽게 이런 흐름에 익숙합니다.
Activity
└ XML Layout
└ View(Button, TextView, RecyclerView ...)
그리고 우리는 오랫동안 다음과 같은 방식으로 UI를 개발해 왔습니다.
textView.text = "Hello"
button.isEnabled = false
recyclerView.adapter.notifyDataSetChanged()
즉:
“화면 객체(View)를 직접 조작하는 방식”
입니다.
하지만 Jetpack Compose는 이 접근 자체를 바꾸려고 등장했습니다.
Compose는 단순히:
XML → Kotlin
변환이 아닙니다.
실제로는:
Control 중심 UI
→
State 중심 UI
로의 패러다임 이동에 가깝습니다.
기존 Android UI 시스템의 구조
전통적인 Android UI 구조는 아래와 같았습니다.
Activity
└ XML Layout
└ View Tree
예를 들어:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
여기서:
Activity의 역할
- 화면 생명주기 관리
- Intent 처리
- 권한 처리
- Navigation 연결
- Window 관리
즉:
Android OS와 연결되는 “화면 컨테이너”
역할을 했습니다.
View/XML의 역할
실제 UI를 그리는 역할입니다.
Button
TextView
RecyclerView
ConstraintLayout
같은 객체(View)를 생성하고 조작했습니다.
예:
button.visibility = View.GONE
즉:
“UI 객체를 직접 수정하는 방식”
입니다.
왜 이 방식이 어려워졌을까?
Android 앱이 커질수록 문제가 생기기 시작했습니다.
예를 들어:
- 화면 상태 증가
- 비동기 처리 증가
- RecyclerView 복잡도 증가
- Lifecycle 문제
- 화면 회전 대응
- Fragment 관리 복잡도
- 상태 동기화 문제
특히 현대 앱은:
실시간 데이터
+
Reactive Stream
+
비동기 이벤트
가 매우 많아졌습니다.
예:
- 채팅
- 지도
- 뉴스 피드
- 실시간 운전 정보
- 스트리밍 UI
- AI 응답 UI
이런 구조에서 “View를 직접 조작”하는 방식은 점점 유지보수가 어려워졌습니다.
Compose의 핵심 철학
Compose는 이 문제를 해결하기 위해 등장했습니다.
핵심 개념은 단 하나입니다.
UI = f(state)
즉:
현재 상태(State)가 무엇인가?
만 정의하면 UI가 자동으로 구성됩니다.
예를 들어 기존 방식은:
button.isEnabled = false
처럼 UI를 직접 수정합니다.
Compose에서는:
Button(
enabled = id.isNotBlank()
)
처럼:
“현재 상태를 선언”
합니다.
Compose는 상태를 보고 화면을 다시 그립니다.
Compose 시대의 구조
Compose에서는 구조가 이렇게 바뀝니다.
Activity
└ Compose Runtime
└ Composable Functions
예:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Greeting("Android")
}
}
}
@Composable
fun Greeting(name: String) {
Text("Hello $name")
}
Activity는 사라진 걸까?
많이 오해하는 부분입니다.
Compose는 Activity를 대체한 것이 아닙니다.
여전히 Activity는 중요합니다.
Activity의 역할
Compose 시대에도 Activity는:
- Lifecycle
- Permission
- Intent
- Navigation Root
- System UI
- Window 관리
등을 담당합니다.
즉:
Android 시스템과 연결되는 Entry Point
역할은 그대로 유지됩니다.
Compose의 역할
Compose는:
- 상태(State)를 입력받아
- UI를 선언하고
- 상태가 바뀌면 다시 그림(Recomposition)
을 담당합니다.
즉:
State → UI
변환 엔진에 가깝습니다.
Compose의 진짜 변화
많은 사람들이 처음 Compose를 보면 이렇게 생각합니다.
“XML 대신 Kotlin 쓰는 거네?”
하지만 실제 핵심은 다릅니다.
Compose는:
객체(View) 중심 UI
를
함수(Function) 중심 UI
로 바꾼 것입니다.
기존 View 시스템
기존 Android는:
Button 객체 생성
→ 속성 변경
→ invalidate()
→ redraw
방식이었습니다.
즉:
Mutable Object Tree 기반 UI
입니다.
Compose 시스템
Compose는:
현재 상태 → UI 함수 실행 → 화면 생성
방식입니다.
즉:
선언형(Declarative) UI
입니다.
Recomposition이라는 개념
Compose에서 매우 중요한 개념이 있습니다.
Recomposition
상태(State)가 바뀌면 필요한 부분만 다시 그리는 메커니즘입니다.
예:
var count by remember {
mutableStateOf(0)
}
Text("$count")
count 값이 바뀌면 Text 부분만 다시 계산됩니다.
Compose는:
State 변화
→ 필요한 UI만 재계산
하는 구조입니다.
Compose가 중요한 이유
Compose의 진짜 의미는 단순 UI Toolkit 변경이 아닙니다.
사실상 Android UI Architecture 전체가 바뀌고 있습니다.
기존 사고
어떻게 View를 조작할까?
Compose 사고
현재 상태를 어떻게 표현할까?
이 변화 때문에 다음 개념들이 중요해졌습니다.
- State Hoisting
- Unidirectional Data Flow
- Reactive UI
- Flow/StateFlow
- Immutable State
- MVI Architecture
Compose는 단순 UI 라이브러리가 아니라:
State 중심 Architecture를 위한 UI 시스템
에 가깝습니다.
현대 Android 구조
요즘 Android 앱은 보통 이렇게 구성됩니다.
MainActivity
└ NavHost
└ Screen Composables
└ UI Components
그리고 데이터 흐름은:
Repository
↓
ViewModel
↓
StateFlow
↓
Compose UI
형태로 연결됩니다.
Compose는 이 reactive 구조와 매우 잘 맞습니다.
Android 개발자에게 중요한 사고 전환
Compose를 배우며 가장 중요한 변화는 이것입니다.
기존 방식
textView.text = "Hello"
즉:
UI 객체를 직접 수정
Compose 방식
Text(text = message)
즉:
현재 상태를 선언
Compose 학습의 핵심은:
View를 어떻게 만들까?
보다
상태 흐름을 어떻게 설계할까?
입니다.
마무리
Compose는 단순히:
XML 대신 Kotlin
이 아닙니다.
실제로는:
Control 중심 UI
→
State 중심 UI
로의 전환입니다.
그리고 이 변화는 단순 UI 기술 변경이 아니라:
- Architecture 변화
- Data Flow 변화
- 상태 관리 방식 변화
- Android 개발 사고방식 변화
까지 포함합니다.
그래서 Compose를 제대로 이해하려면:
“UI를 어떻게 그릴까?”
보다
“현재 상태를 어떻게 표현할까?”
를 먼저 고민해야 합니다.
다음 글에서는:
“Android 개발자의 사고는 Compose에서 어떻게 바뀌는가?”
를 실제 예제를 통해 살펴보겠습니다.
'Android Programming' 카테고리의 다른 글
| ViewModel에서 Factory 사용 여부 비교 (0) | 2025.03.25 |
|---|---|
| Modern Anroid Application의 UI 구조 이해 (0) | 2025.03.18 |
| Modern Anroid Application의 구조 이해 (1) | 2025.03.11 |
| Waydroid 설정하기 (2) | 2022.04.15 |