Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jetpack Compose: Beyond I/O 2021

Jetpack Compose: Beyond I/O 2021

Google I/O Extended Korea Android 발표 자료입니다.

Sa-ryong Kang

July 02, 2021
Tweet

More Decks by Sa-ryong Kang

Other Decks in Technology

Transcript

  1. 1
    Jetpack Compose:
    I/O 2021 그 이후
    Speaker
    Saryong Kang
    Partner Developer Advocate @ Google Japan
    https://speakerdeck.com/saryong

    View Slide

  2. Disclaimer
    ● 이 발표에서 나오는 설명, 해설 및 참고 자료는 Google의 공식적
    내용이
    아닐 수 있습니다.
    ● 기술에 대한 의견, 평가는 어디까지나 개인적인 의견입니다.
    2

    View Slide

  3. 3
    02 Compose로 더 행복해지는 앱 개발
    01 I/O 2021 Quick Recap
    03 Compose 개발이 처음이라면
    04 실전 Compose!
    05 FAQ

    View Slide

  4. Anna-Chiara Bellini
    @dr0nequeen
    Clara Bayarri
    @clarabayarri
    What’s new in Jetpack
    Compose

    View Slide

  5. ● 왜 Compose를 만들었는가?
    ● 왜 선언형 UI인가?
    ● 샘플 프로젝트 OWL을 통한 UI 구현 데모
    5
    What’s new in Jetpack
    Compose

    View Slide

  6. Manuel Vicente Vivo - Developer Relations Engineer, Google
    @manuelvicnt
    Using Jetpack libraries
    in Compose
    6
    Ian Lake - Software Engineer, Google
    @ianhlake

    View Slide

  7. ● 샘플 프로젝트 Bloom 소개
    ● ViewModel를 중심으로 Compose 앱에서 어떻게 상태를 관리하는가
    설명
    ● 기존 앱의 마이그레이션 전략
    ● Compose에서 Navigation 구현 방법 소개
    7
    Using Jetpack libraries
    in Compose

    View Slide

  8. ● Owl샘플 프로젝트를 이용해 디자인을 어떻게 적용하는가를 설명
    ● Compose에서 체계적으로 색상, 폰트, 모양(shape)을 지정하는 방법
    ● Scaffold등 Material Design Component의 Composable 사용 방법
    ● Dark mode대응
    ● MDC-Android Compose Theme Adapter
    8
    Build beautiful Material Design
    apps with Jetpack Compose

    View Slide

  9. ● Accessibility Test Framework for Android (ATF)의 체크 결과가
    Android Studio에 표시됨
    ● Jetpack Compose의 접근성 대응에 대해서 소개
    9
    Designing for accessibility in
    Android Studio and Jetpack
    Compose

    View Slide

  10. 10
    02 Compose로 더 행복해지는 앱 개발
    01 I/O 2021 Quick Recap
    03 Compose 개발이 처음이라면
    04 실전 Compose!
    05 FAQ

    View Slide

  11. XML Layout
    Button
    LinearLayout
    TextView

    View Slide

  12. Button
    LinearLayout
    TextView
    XML Layout
    findViewById()
    Activity / Fragment
    tv.setText()
    b.setVisibility()
    vg.addView()

    View Slide

  13. Button
    LinearLayout
    TextView
    XML Layout
    findViewById()
    Activity / Fragment
    tv.setText()
    b.setVisibility()
    vg.addView()
    State

    View Slide

  14. Button
    LinearLayout
    TextView
    XML Layout
    findViewById()
    Activity / Fragment
    tv.setText()
    b.setVisibility()
    vg.addView()
    State
    State

    View Slide

  15. Button
    LinearLayout
    TextView
    XML Layout
    findViewById()
    Activity / Fragment
    tv.setText()
    b.setVisibility()
    vg.addView()
    State
    State
    State
    State
    State

    View Slide

  16. Button
    LinearLayout
    TextView
    XML Layout
    findViewById()
    Activity / Fragment
    tv.setText()
    b.setVisibility()
    vg.addView()
    State
    State
    State
    State
    State

    View Slide

  17. UI
    State

    View Slide

  18. UI
    State 2

    View Slide

  19. UI 2
    State 2

    View Slide

  20. UI 2
    State 2

    View Slide

  21. @Composable
    fun HomeScreen() {
    var counter by remember { mutableStateOf(0) }
    Column {
    Text(text = "현재값: $counter")
    Button(onClick = { counter++ }) {
    Text("더하기 1")
    }
    }
    }

    View Slide

  22. @Composable
    fun HomeScreen() {
    var counter by remember { mutableStateOf(0) }
    Column {
    Text(text = "현재값: $counter")
    Button(onClick = { counter++ }) {
    Text("더하기 1")
    }
    }
    }

    View Slide

  23. @Composable
    fun HomeScreen() {
    var counter by remember { mutableStateOf(0) }
    Column {
    Text(text = "현재값: $counter")
    Button(onClick = { counter++ }) {
    Text("더하기 1")
    }
    }
    }

    View Slide

  24. @Composable
    fun HomeScreen() {
    var counter by remember { mutableStateOf(0) }
    Column {
    Text(text = "현재값: $counter")
    Button(onClick = { counter++ }) {
    Text("더하기 1")
    }
    }
    }

    View Slide

  25. @Composable
    fun HomeScreen() {
    var counter by remember { mutableStateOf(0) }
    Column {
    Text(text = "현재값: $counter")
    Button(onClick = { counter++ }) {
    Text("더하기 1")
    }
    }
    }

    View Slide

  26. @Composable
    fun HomeScreen() {
    var counter by remember { mutableStateOf(0) }
    Column {
    Text(text = "현재값: $counter")
    Button(onClick = { counter++ }) {
    Text("더하기 1")
    }
    }
    }

    View Slide

  27. ● 방대한 코드 베이스로 인해 기술적 부채의 해소가 어려워짐
    ● 새로운 디자인 언어(design language)의 구현이 기존 View
    구조에서는 어려웠음
    ● 전체 앱을 Compose 기반으로 바꾸는 작업을 작년부터 진행 중
    ● 많은 양의 feature request / feedback으로 함께 미래를 만들어 가고
    있음
    ● “다시는 이전의 View 기반으로 돌아가고 싶지 않다”
    ● Ref: d.android.com/stories/apps/mercari 27
    사례: Mercari

    View Slide

  28. 28
    03 Compose 개발이 처음이라면
    04 실전 Compose!
    05 FAQ
    01 I/O 2021 Quick Recap
    02 Compose로 더 행복해지는 앱 개발

    View Slide

  29. ● 먼저 Pathways!
    d.android.com/courses/pathways/compose
    29
    어떻게 공부하면 되나?

    View Slide

  30. 30
    ● 3개의 비디오 강의
    ● 2개의 글
    ● 7개의 코드랩
    ● 1개의 퀴즈

    View Slide

  31. 31
    Google 공식 자료들
    ● 공식 샘플 프로젝트 - 주제별로 8개의 다양한 샘플 프로젝트
    goo.gle/compose-samples
    ● 코드랩 모음
    goo.gle/compose-codelabs
    ● 각종 가이드문서
    goo.gle/compose-docs
    (Foundation 파트, 그 중에서도 Thinking in Jetpack Compose!)

    View Slide

  32. 32
    Accompanist: 필수 라이브러리
    ● Compose 안에서 제공하기 애매한 기능들
    ○ 이미지 로딩: Coil, Glide
    ● 각종 실험적인 기능들
    ○ Insets
    ○ Pager
    ○ Swipe to Refresh
    ○ Permissions
    ● 그 외 각종 실험 예제 - eg. non-AAC state 관리

    View Slide

  33. ● View Compose mapping table
    https://jetpackcompose.app/What-is-the-equivalent-of-CardView-in-Jetpack-Compose
    예: FrameLayout → Stack, SeekBar → Slider, EditText → TextField
    ● Learn Jetpack Compose By Example
    https://github.com/vinaygaba/Learn-Jetpack-Compose-By-Example
    ● Joe Birch Blog - Exploring Jetpack Compose
    https://joebirch.co/
    ● 그리고, 여러분..
    33
    그외 비 Google 자료 (초급)

    View Slide

  34. ● Compose From First Principles by Leland Richardson
    http://intelligiblebabble.com/compose-from-first-principles/
    ● Compose State Explained Series by Zach Klippenstein
    https://dev.to/zachklipp/series/12895
    ● Tivi by Chris Banes
    https://github.com/chrisbanes/tivi
    ● 그리고..
    34
    그외 비 Google 자료 (중급)

    View Slide

  35. 35
    04 실전 Compose!
    05 FAQ
    01 I/O 2021 Quick Recap
    02 Compose로 더 행복해지는 앱 개발
    03 Compose 개발이 처음이라면

    View Slide

  36. ● State Hoisting
    ● ViewModel
    ● CompositionLocal
    하위 노드에서 접근 가능. Dimension 데이터 등 전역으로 관리하는 상태를 넘겨주기에 적합
    36
    중요 개념: 상태 전달

    View Slide

  37. ● Composable 외부로부터 영향을 받는 부수작용을 처리하기 위한 Composable
    ○ SideEffect / DisposableEffect
    ○ Eg. 서버 호출, DB 쿼리 등
    37
    중요 개념: SideEffect

    View Slide

  38. 38
    중요 개념: Custom Layout
    ● Modifier.layout → 같은 프레임을 빠르게 그려줌
    ○ 부모 트리의 영향을 받는 개발 composable의 size/padding을 변경하는 경우에 추천
    ○ 구조적인 변경(orientation, positioning)엔 적합하지 않음
    ● Modifier.onSizeChanged
    ○ 데이터 로딩 등을 위해 사이즈 정보가 필요한 경우에 추천
    ○ MutableState 전달에 의해 그린다면 한 프레임씩 지연이 생김에 주의
    ● WithConstraints → 같은 프레임에 그리지만 subcomposition이 일어남
    ○ 구조적인 변경에 추천

    View Slide

  39. ● UI의 재구축(recomposition)은 될 수 있는 한 skip되도록 설계되어 있다.
    Ref: d.android.com/jetpack/compose/mental-model#skips
    ● 어디서 재구축이 어떻게 일어나는 지 이해하지 않아도 괜찮음. Compose compiler/runtime이
    알아서..
    39
    중요 개념: Position
    Memoization

    View Slide

  40. data class State(
    val firstCounter: Int = 0,
    val secondCounter: Int = 0
    )
    @Composable
    fun HomeScreen(
    stateFlow: StateFlow,
    onClick1: () -> Unit,
    onClick2: () -> Unit,
    ) {
    val state by stateFlow.collectAsState()
    Column {
    Button(onClick = onClick1) {
    Text(text = "첫째 카운터: ${state.firstCounter}")
    }
    Button(onClick = onClick2) {
    Text(text = "둘째 카운터 ${state.secondCounter}")
    }
    }
    }

    View Slide

  41. data class State(
    val firstCounter: Int = 0,
    val secondCounter: Int = 0
    )
    @Composable
    fun HomeScreen(
    stateFlow: StateFlow,
    onClick1: () -> Unit,
    onClick2: () -> Unit,
    ) {
    val state by stateFlow.collectAsState()
    Column {
    Button(onClick = onClick1) {
    Text(text = "첫째 카운터: ${state.firstCounter}")
    }
    Button(onClick = onClick2) {
    Text(text = "둘째 카운터 ${state.secondCounter}")
    }
    }
    }

    View Slide

  42. data class State(
    val firstCounter: Int = 0,
    val secondCounter: Int = 0
    )
    @Composable
    fun HomeScreen(
    stateFlow: StateFlow,
    onClick1: () -> Unit,
    onClick2: () -> Unit,
    ) {
    val state by stateFlow.collectAsState()
    Column {
    Button(onClick = onClick1) {
    Text(text = "첫째 카운터: ${state.firstCounter}")
    }
    Button(onClick = onClick2) {
    Text(text = "둘째 카운터 ${state.secondCounter}")
    }
    }
    }

    View Slide

  43. data class State(
    val firstCounter: Int = 0,
    val secondCounter: Int = 0
    )
    @Composable
    fun HomeScreen(
    stateFlow: StateFlow,
    onClick1: () -> Unit,
    onClick2: () -> Unit,
    ) {
    val state by stateFlow.collectAsState()
    Column {
    Button(onClick = onClick1) {
    Text(text = "첫째 카운터: ${state.firstCounter}")
    }
    Button(onClick = onClick2) {
    Text(text = "둘째 카운터 ${state.secondCounter}")
    }
    }
    }

    View Slide

  44. ● 딱 두 가지 유의점
    ○ inline composable 함수
    ○ Composition 비용이 많이 들 것 같은 경우는, 관계없는 상태에 영향을 받지 않도록 분리할
    필요가 있음
    44
    Tip: Recomposition 최적화

    View Slide

  45. ● 하나의 Preview Composable에 옵션별로 여러 개의 @Preview 애너테이션 달기
    ○ 평소에는 작은 사이즈(eg. 360dp X 640dp)만 활성화
    ● “Deploy Preview” 기능
    ● 참고: 현재 rc01 에서 프리뷰가 보이지 않는 문제는 차기 Android Studio 릴리즈에서
    해결됩니다
    45
    Tip: Preview

    View Slide

  46. @Preview(name = "Day mode, small screen", widthDp = 360, heightDp = 640)
    @Preview(
    name = "Night mode, small screen", widthDp = 360, heightDp = 640,
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    )
    @Preview("Day mode, big font", fontScale = 1.5f)
    @Preview(name = "Day mode", device = Devices.PIXEL_4)
    @Composable
    fun PreviewHome() {
    MyApplicationTheme {
    Surface(color = MaterialTheme.colors.background) {
    HomeScreen()
    }
    }
    }

    View Slide

  47. ● 전통적인 Android View에서는 할 수 있는 한 nest 되지 않는 것이 관건이지만,
    Compose에서는 문제가 되지 않음
    ● 반대로, 앞서 얘기한 이유로, nesting을 줄이면 오히려 성능이 급격히 저하되는 경우가 많음
    47
    Tip: ConstraintLayout

    View Slide

  48. ● Color를 resource로부터 얻지 말고 Kotlin 코드로 정의할 것 (JNI call 발생)
    ● · 과 같은 유니코드 문자를 빈번히 렌더링할 경우, Text() 대신 Canvas() 사용을 검토할 것 →
    훨씬 빠름
    48
    Tip: 그외 깨알 성능 팁

    View Slide

  49. 49
    05 FAQ
    01 I/O 2021 Quick Recap
    02 Compose로 더 행복해지는 앱 개발
    03 Compose 개발이 처음이라면
    04 실전 Compose!

    View Slide

  50. Compose가 널리
    보급되면 기존의 View
    구현 방식은 deprecated
    되나요?
    50

    View Slide

  51. XML 자체도 필요없게
    될까요?
    51

    View Slide

  52. 기존 Android View와
    섞어써도 문제 없을까요?
    52

    View Slide

  53. Compose를 쓰면 여러
    가지 종류의 폼팩터
    (form factor) 지원도
    쉬워지나요?
    53

    View Slide

  54. ● 이미 가능!
    https://github.com/chrisbanes/tivi/pull/806/files#diff-2107f2dfb7cd4fe4cf4775d762d2166
    afaca1a3625361e58389a0772b179e2a2
    ● Stay tunes!
    더 강력한 multi form factor 지원이 발표될 예정입니다.
    ● Wear OS용 컴포즈 alpha01 릴리즈! 🎉
    54

    View Slide

  55. Thank you!
    https://speakerdeck.com/saryong
    Resources
    55
    Saryong Kang
    Partner Developer Advocate @ Google Japan

    View Slide