Jetpack Compose Part 2 — Preview / Layout / Decompile

이기정
Android Deep-Dive Study
7 min readApr 8, 2021

목차

Android Studio의 Jetpack Compose

Android Studio Preview를 사용해 Compose를 사용하다보면 Preview라 코드레벨에서 활성화되는 것을 알 수 있다.

좀 더 자세히 살펴보자.

Preview의 기능들

Preview 와 Compose 를 사용해서 아래와 같이 구성할 수 있다.

Split(design/code) 을 선택에 따라 코드 및 디자인의 패널을 변경할 수도 있다.

미리보기에서 인터렉티브 모드를 설정할 수 있다.

인터렉티브 모드를 설정하면 실제 디바이스처럼 클릭이나 드래그 등의 상호 작용을 확인해 볼 수 있다.

다만, 네트워크나 파일에 접근 또는 일부 Context API 는 인터렉티브 모드를 지원하지 않고 있다.

간헐적으로 interactive 모드가 작동하지 않는 경우가 있다.

미리보기에서 직접 디바이스 혹은 에뮬레이터로 배포하여 결과를 확인할 수도 있다.

@Preview Annotation 분석

위에서 언급했다시피 @Preview 를 사용하면 디바이스나 에뮬레이터를 실행하지 않고 실시간으로 Compose UI 를 볼 수 있다.

@Preview 를는 아래와 같이 구성되어 있으며 설정에 따라서 미리보기를 다양하게 구성할 수 있다.

Preview.kt
  • name : Preview 의 이름을 지정하며, 기본 값은 function 이름으로 설정된다.
  • group : Preview 의 그룹을 지정한다, 기본 값은 function 이름으로 설정된다.
  • apiLevel : api level 설정에 따라 Composable 을 렌더링해준다.
  • widthDp : Preview 의 너비를 설정한다. (기본 단위는 dp)
  • heightDp : Preview 의 높이를 설정한다. (기본 단위는 dp)
  • locale : 사용자 locales 에 따라 보여지는 UI 를 테스트 하기 위해 사용한다.
  • fontScale : 기본 density 애 배율을 적용해서 폰트 사이즈를 변경할 수 있다.
  • showSystemUi : true 로 설정하면 status bar 와 action bar 를 노출한다.
  • showBackground : true 로 설정하면 기본 배경색상을 적용해준다.
  • backgroundColor : 미리보기의 배경색을 설정할 수 있으며, showBackground 설정에 따라 노출 유무를 결정한다.
  • uiMode : uiMode 를 설정한다.
  • device : 기존 정의된 디바이스를 프리뷰에 적용한다. Devices object 에 정의된 값을 선택해서 사용할 수 있습니다. (Devices.NEXUS_9)

Compose의 레이아웃 구성

  • Column : 아이템을 세로로 배치한다.
  • Row : 아이템을 가로로 배치한다.
  • Box : 구성 요소를 다른 구성 요소 위에 배치한다.
  • Modifier : 구성 요소의 크기, 마진등을 변경하거나 클릭이나 스크롤 등의 이벤트를 제어할 수 있도록 한다.
  • LazyColumn / LazyRow : Recyclerview 유사하게 화면에 보여지는 구성 요소만을 렌더링한다. 큰 데이터셋을 다루기에 용이하다.
  • ConstraintLayout : 기존 ContraintLayout 과 같이 여러 제약 참조를 설정해서 사용할 수 있다. createRefs / createRefFor 를 통해 참조를 생성하며, constrainAs 를 통해 제약 조건을 설정한다.

Jetpack Compose 의 ConstraintLayout 을 사용하기 위해서는 아래 의존성을 추가해야 한다.

Jetpack Compose의 동작 원리 파악을 위한 빌드 과정 추적

1. 프로젝트 생성

Compose가 내부적으로 어떻게 동작하는 지 알아보기 위해 먼저 프로젝트를 빌드해보자.

빌드 후 Kotlin > Byte Code > Decompiled Java 순서로 변환하여 살펴볼 것이다.

Android Studio Preview에서 Empty Compose Activity로 프로젝트를 생성하면 아래와 같은 샘플 코드를 얻을 수 있다.

프로젝트 생성 후 임의로 Hello World로 파라미터값을 변경하였다.

부가적으로 src 폴더 내부에 ui.theme 패키지가 생성되고 Color.kt, Shape.kt, Theme.kt, Type.kt 파일도 생성된다.

이 파일들은 필요한 경우 들여다 보도록 하자.

생성 후 Preview에 아래와 같이 렌더링 된다.

2. MainActivity 디컴파일

ComponentActivityKt.setContent() 의 구현체는 아래와 같다.

CompositionContext 파라미터는 null을 그대로 넘겨주었고, (Function0)null.INSTANCE, 1, (Object)null 의 값으로 무언가를 넘겨주는데, 이 값이 @Composable Annotation의 구현체이다.

위의 코드 흔적을 술어로 표현해보면 @Composable 구현체를 넘겨주면 이를 기반으로 ComposeView 객체를 생성하여 ActivitysetContentView()에 적용한다. 가 되겠다.

3. @Composable 구현체 확인

Composable Annotaion 클래스의 구현체는 아래와 같다.

AnnotationTarget을 통해 메서드나 Lambda 객체를 넘겨서 뷰를 조립하는 방식인데, ViewViewGroup 처럼 내부적으로 트리 구조로 실행지점에 대한 정보를 저장하고 있다.

파면 팔수록 Flutter의 Widget, React Native의 Component와 유사한 느낌을 준다.

해당 포스트는 아래 팀원들과 함께 작성되었습니다.

  • 김남훈 @Naver
  • 배희성 @RocketPunch
  • 송시영 @SmartStudy
  • 이기정 @BankSalad

--

--

이기정
Android Deep-Dive Study

사회공헌을 위한 개발을 좋아합니다. 최근엔 안드로이드 플랫폼을 기반으로하는 Reactive Programing에 관심이 많습니다.