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 발표 자료입니다.

1ff3242c5f6acd42dcccecdbef78961f?s=128

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
  2. Disclaimer • 이 발표에서 나오는 설명, 해설 및 참고 자료는

    Google의 공식적 내용이 아닐 수 있습니다. • 기술에 대한 의견, 평가는 어디까지나 개인적인 의견입니다. 2
  3. 3 02 Compose로 더 행복해지는 앱 개발 01 I/O 2021

    Quick Recap 03 Compose 개발이 처음이라면 04 실전 Compose! 05 FAQ
  4. Anna-Chiara Bellini @dr0nequeen Clara Bayarri @clarabayarri What’s new in Jetpack

    Compose
  5. • 왜 Compose를 만들었는가? • 왜 선언형 UI인가? • 샘플

    프로젝트 OWL을 통한 UI 구현 데모 5 What’s new in Jetpack Compose
  6. Manuel Vicente Vivo - Developer Relations Engineer, Google @manuelvicnt Using

    Jetpack libraries in Compose 6 Ian Lake - Software Engineer, Google @ianhlake
  7. • 샘플 프로젝트 Bloom 소개 • ViewModel를 중심으로 Compose 앱에서

    어떻게 상태를 관리하는가 설명 • 기존 앱의 마이그레이션 전략 • Compose에서 Navigation 구현 방법 소개 7 Using Jetpack libraries in Compose
  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
  9. • Accessibility Test Framework for Android (ATF)의 체크 결과가 Android

    Studio에 표시됨 • Jetpack Compose의 접근성 대응에 대해서 소개 9 Designing for accessibility in Android Studio and Jetpack Compose
  10. 10 02 Compose로 더 행복해지는 앱 개발 01 I/O 2021

    Quick Recap 03 Compose 개발이 처음이라면 04 실전 Compose! 05 FAQ
  11. XML Layout Button LinearLayout TextView

  12. Button LinearLayout TextView XML Layout findViewById() Activity / Fragment tv.setText()

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

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

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

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

    b.setVisibility() vg.addView() State State State State State
  17. UI State

  18. UI State 2

  19. UI 2 State 2

  20. UI 2 State 2

  21. @Composable fun HomeScreen() { var counter by remember { mutableStateOf(0)

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

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

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

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

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

    } Column { Text(text = "현재값: $counter") Button(onClick = { counter++ }) { Text("더하기 1") } } }
  27. • 방대한 코드 베이스로 인해 기술적 부채의 해소가 어려워짐 •

    새로운 디자인 언어(design language)의 구현이 기존 View 구조에서는 어려웠음 • 전체 앱을 Compose 기반으로 바꾸는 작업을 작년부터 진행 중 • 많은 양의 feature request / feedback으로 함께 미래를 만들어 가고 있음 • “다시는 이전의 View 기반으로 돌아가고 싶지 않다” • Ref: d.android.com/stories/apps/mercari 27 사례: Mercari
  28. 28 03 Compose 개발이 처음이라면 04 실전 Compose! 05 FAQ

    01 I/O 2021 Quick Recap 02 Compose로 더 행복해지는 앱 개발
  29. • 먼저 Pathways! d.android.com/courses/pathways/compose 29 어떻게 공부하면 되나?

  30. 30 • 3개의 비디오 강의 • 2개의 글 • 7개의

    코드랩 • 1개의 퀴즈
  31. 31 Google 공식 자료들 • 공식 샘플 프로젝트 - 주제별로

    8개의 다양한 샘플 프로젝트 goo.gle/compose-samples • 코드랩 모음 goo.gle/compose-codelabs • 각종 가이드문서 goo.gle/compose-docs (Foundation 파트, 그 중에서도 Thinking in Jetpack Compose!)
  32. 32 Accompanist: 필수 라이브러리 • Compose 안에서 제공하기 애매한 기능들

    ◦ 이미지 로딩: Coil, Glide • 각종 실험적인 기능들 ◦ Insets ◦ Pager ◦ Swipe to Refresh ◦ Permissions • 그 외 각종 실험 예제 - eg. non-AAC state 관리
  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 자료 (초급)
  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 자료 (중급)
  35. 35 04 실전 Compose! 05 FAQ 01 I/O 2021 Quick

    Recap 02 Compose로 더 행복해지는 앱 개발 03 Compose 개발이 처음이라면
  36. • State Hoisting • ViewModel • CompositionLocal 하위 노드에서 접근

    가능. Dimension 데이터 등 전역으로 관리하는 상태를 넘겨주기에 적합 36 중요 개념: 상태 전달
  37. • Composable 외부로부터 영향을 받는 부수작용을 처리하기 위한 Composable ◦

    SideEffect / DisposableEffect ◦ Eg. 서버 호출, DB 쿼리 등 37 중요 개념: SideEffect
  38. 38 중요 개념: Custom Layout • Modifier.layout → 같은 프레임을

    빠르게 그려줌 ◦ 부모 트리의 영향을 받는 개발 composable의 size/padding을 변경하는 경우에 추천 ◦ 구조적인 변경(orientation, positioning)엔 적합하지 않음 • Modifier.onSizeChanged ◦ 데이터 로딩 등을 위해 사이즈 정보가 필요한 경우에 추천 ◦ MutableState 전달에 의해 그린다면 한 프레임씩 지연이 생김에 주의 • WithConstraints → 같은 프레임에 그리지만 subcomposition이 일어남 ◦ 구조적인 변경에 추천
  39. • UI의 재구축(recomposition)은 될 수 있는 한 skip되도록 설계되어 있다.

    Ref: d.android.com/jetpack/compose/mental-model#skips • 어디서 재구축이 어떻게 일어나는 지 이해하지 않아도 괜찮음. Compose compiler/runtime이 알아서.. 39 중요 개념: Position Memoization
  40. data class State( val firstCounter: Int = 0, val secondCounter:

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

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

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

    Int = 0 ) @Composable fun HomeScreen( stateFlow: StateFlow<State>, onClick1: () -> Unit, onClick2: () -> Unit, ) { val state by stateFlow.collectAsState() Column { Button(onClick = onClick1) { Text(text = "첫째 카운터: ${state.firstCounter}") } Button(onClick = onClick2) { Text(text = "둘째 카운터 ${state.secondCounter}") } } }
  44. • 딱 두 가지 유의점 ◦ inline composable 함수 ◦

    Composition 비용이 많이 들 것 같은 경우는, 관계없는 상태에 영향을 받지 않도록 분리할 필요가 있음 44 Tip: Recomposition 최적화
  45. • 하나의 Preview Composable에 옵션별로 여러 개의 @Preview 애너테이션 달기

    ◦ 평소에는 작은 사이즈(eg. 360dp X 640dp)만 활성화 • “Deploy Preview” 기능 • 참고: 현재 rc01 에서 프리뷰가 보이지 않는 문제는 차기 Android Studio 릴리즈에서 해결됩니다 45 Tip: Preview
  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() } } }
  47. • 전통적인 Android View에서는 할 수 있는 한 nest 되지

    않는 것이 관건이지만, Compose에서는 문제가 되지 않음 • 반대로, 앞서 얘기한 이유로, nesting을 줄이면 오히려 성능이 급격히 저하되는 경우가 많음 47 Tip: ConstraintLayout
  48. • Color를 resource로부터 얻지 말고 Kotlin 코드로 정의할 것 (JNI

    call 발생) • · 과 같은 유니코드 문자를 빈번히 렌더링할 경우, Text() 대신 Canvas() 사용을 검토할 것 → 훨씬 빠름 48 Tip: 그외 깨알 성능 팁
  49. 49 05 FAQ 01 I/O 2021 Quick Recap 02 Compose로

    더 행복해지는 앱 개발 03 Compose 개발이 처음이라면 04 실전 Compose!
  50. Compose가 널리 보급되면 기존의 View 구현 방식은 deprecated 되나요? 50

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

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

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

    53
  54. • 이미 가능! https://github.com/chrisbanes/tivi/pull/806/files#diff-2107f2dfb7cd4fe4cf4775d762d2166 afaca1a3625361e58389a0772b179e2a2 • Stay tunes! 더 강력한

    multi form factor 지원이 발표될 예정입니다. • Wear OS용 컴포즈 alpha01 릴리즈! 🎉 54
  55. Thank you! https://speakerdeck.com/saryong Resources 55 Saryong Kang Partner Developer Advocate

    @ Google Japan