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

Kotlin Multiplatform MobileのおさらいとABEMAでのマルチプラット...

Kotlin Multiplatform MobileのおさらいとABEMAでのマルチプラットフォーム対応

近年,技術的なトレンドとしてKMM(Kotlin Multiplatform Mobile)やFlutter,React Nativeといったマルチプラットフォーム・クロスプラットフォーム技術が注目を浴びています。
Kotlinは2018年にリリースしたKotlin 1.3から,AndroidとiOSを含む様々なプラットフォーム間でのコードの共通化が可能になり,今年(2022年)にはKMMのベータ版リリースが予定されています。

様々なプラットフォームにサービスを展開しているABEMAでも,このKMMによってプラットフォーム間でのコードの共通化に取り組んでいます。

このセッションでは,特にモバイルプラットフォームにフォーカスを当ててKotlin Multiplatformのこれまでを振り返りつつ,ABEMAにおけるKMMの活用事例や開発している中での様々な知見を紹介します。

CyberAgent

July 08, 2022
Tweet

More Decks by CyberAgent

Other Decks in Technology

Transcript

  1. 1. Kotlin Multiplatform MobileʢKMMʣͱ͸ 2. Kotlin Multiplatformͷ͜Ε·Ͱ 3. Kotlin Multiplatformͷ࢓૊Έ

    4. νʔϜͰಋೖɾӡ༻͍ͯ͘͠ʹ͸ 5. KMMͷ՝୊ͱকདྷੑ 6. ࠷ۙͷτϐοΫε
  2. Kotlin Multiplatform / KMP / KMM • KotlinʹΑͬͯෳ਺ϓϥοτϑΥʔϜͷ։ൃΛߦ͏ٕज़΍ ΤίγεςϜશମ Kotlin

    Multiplatform Kotlin Multiplatform Project (KMP) • Kotlin MultiplatformΛ༻͍ͯ։ൃ͞ΕΔϓϩδΣΫτ
  3. Kotlin Multiplatform Mobile (KMM)? 🤝 https://youtu.be/PW-jkOLucjM?t=274 ⚙ Kotlin Multiplatform Multiplatform

    Gradle DSL Kotlin + Kotlin/JVM + Kotlin/Native + … Android Studio Plugin + CocoaPods integration + … 📱 Mobile Features SDK for cross-platform mobile development OFFICIAL
  4. Flutter΍UnityͳͲͱͷҧ͍͸ʁ • ֤ϓϥοτϑΥʔϜͰΞϓϦέʔγϣϯ͕ϥϯλΠϜͰಈ ࡞͢Δ࣮ߦ؀ڥΛඞཁͱ͢Δ • UI·Ͱڞ௨Խ͢Δ͜ͱ͕Մೳ Flutter, Unity… Kotlin Multiplatform

    • ಛఆͷ࣮ߦ؀ڥΛඞཁͱ͠ͳ͍ • KotlinΛ֤ϓϥοτϑΥʔϜͰಈ࡞͢ΔNativeίʔυʹม ׵͢Δ • ݱ࣌఺Ͱ͸iOSͷUIڞ௨ԽΛެ͕ࣜαϙʔτ͍ͯ͠ͳ͍
  5. Kotlin 1.1 2016/02 Kotlin 1.2 2017/11 Kotlin 1.3 2018/10 Kotlin

    1.4 2020/08 Kotlin 1.5 2021/05 Kotlin 1.6 2021/11 Kotlin 1.7 2022/06 KotlinΛJSʹίϯύΠϧ͢ΔػೳʢKotlin/JSʣ͕Stableʹ JVMͱJS؀ڥͷιʔείʔυڞ௨Խ͕Մೳʹ Kotlin/Native Beta (v1.0.1) Kotlin Multiplatform Mobile Alpha Hierarchical project structure Kotlin NativeͷύϑΥʔϚϯεվળ Experimental new memory manager Alpha new memory manager
  6. Kotlin 1.1 2016/02 Kotlin 1.2 2017/11 Kotlin 1.3 2018/10 Kotlin

    1.4 2020/08 Kotlin 1.5 2021/05 Kotlin 1.6 2021/11 Kotlin 1.7 2022/06 KotlinΛJSʹίϯύΠϧ͢Δػೳ(Kotlin/JS)͕Stableʹ JVMͱJS؀ڥͷιʔείʔυڞ௨Խ͕Մೳʹ Kotlin/Native Beta (v1.0.1) Kotlin Multiplatform Mobile Alpha Hierarchical project structure Kotlin NativeͷύϑΥʔϚϯεվળ Experimental new memory manager Alpha new memory manager https://blog.jetbrains.com/kotlin/2017/11/kotlin-1-2-released/
  7. Kotlin 1.1 2016/02 Kotlin 1.2 2017/11 Kotlin 1.3 2018/10 Kotlin

    1.4 2020/08 Kotlin 1.5 2021/05 Kotlin 1.6 2021/11 Kotlin 1.7 2022/06 KotlinΛJSʹίϯύΠϧ͢Δػೳ(Kotlin/JS)͕Stableʹ JVMͱJS؀ڥͷιʔείʔυڞ௨Խ͕Մೳʹ Kotlin/Native Beta (v1.0.1) Kotlin Multiplatform Mobile Alpha Hierarchical project structure Kotlin NativeͷύϑΥʔϚϯεվળ Experimental new memory manager Alpha new memory manager https://youtu.be/3uVUDsoE_5U?t=220
 https://blog.jetbrains.com/kotlin/2020/08/kotlin-multiplatform-mobile-goes-alpha/
  8. Kotlin 1.1 2016/02 Kotlin 1.2 2017/11 Kotlin 1.3 2018/10 Kotlin

    1.4 2020/08 Kotlin 1.5 2021/05 Kotlin 1.6 2021/11 Kotlin 1.7 2022/06 KotlinΛJSʹίϯύΠϧ͢Δػೳ(Kotlin/JS)͕Stableʹ JVMͱJS؀ڥͷιʔείʔυڞ௨Խ͕Մೳʹ Kotlin/Native Beta (v1.0.1) Kotlin Multiplatform Mobile Alpha Hierarchical project structure Kotlin NativeͷύϑΥʔϚϯεվળ Experimental new memory manager Alpha new memory manager https://blog.jetbrains.com/kotlin/2021/08/try-the-new-kotlin-native-memory-manager-development-preview/
  9. How Kotlin Multiplatform works • KotlinͷίϯύΠϥʹ͸FrontendͱBackend͕͋ Γɼڞ௨ͷFrontendͰதؒදݱʹม׵ޙɼ֤ϓϥοτ ϑΥʔϜͷBackendΛ௨ͯ͡όΠφϦʹม׵͞ΕΔ • ঃʑʹҠߦத

    🏃 K2 Compiler https://youtu.be/3uVUDsoE_5U?t=303 Kotlin Ecosystem • ϓϥοτϑΥʔϜڞ௨ͷϥΠϒϥϦ΍API • + ϓϥοτϑΥʔϜݻ༗ͷAPI • Kotlin/JVM, Kotlin/JS, Kotlin/Wasm, Kotlin/Native
  10. Code sharing • commonιʔεηοτʹڞ௨ϓϥοτϑΥʔϜͷ࣮૷Λஔ ͘͜ͱ͕Ͱ͖Δ • ϓϥοτϑΥʔϜಛ༗ͷιʔεηοτ΋࣋ͯΔ • Hierarchical project

    structureʹΑͬͯɼ͍ۙ؀ڥͷϓ ϥοτϑΥʔϜΛڞ௨Խͨ͠ιʔεηοτ΋࡞ΕΔ https://kotlinlang.org/docs/multiplatform.html#how-kotlin-multiplatform-works
  11. Target platforms • JVM • JS (browser/Node.js) • Android •

    Android NDK (ARM32/ARM64/x86/x86_64) • iOS (ARM32/ARM64/iOS simulator) • watchOS (ARM32/ARM64/watchOS simulator) • tvOS (ARM64/tvOS simulator) • macOS (x86_64/Apple Silicon) • Linux (ARM32/ARM64/MIPS/mipsel/x86_64) • Windows (32-bit Windows/64-bit Windows) • WebAssembly https://kotlinlang.org/docs/multiplatform-dsl-reference.html#targets
  12. Build configuration kotlin { android() listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach

    { it.binaries.framework { baseName = "base" } } sourceSets { val commonMain by getting { dependencies { // … } } val commonTest by getting val androidMain by getting val androidTest by getting val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) } val iosX64Test by getting val iosArm64Test by getting val iosSimulatorArm64Test by getting val iosTest by creating { dependsOn(commonTest) iosX64Test.dependsOn(this) iosArm64Test.dependsOn(this) iosSimulatorArm64Test.dependsOn(this) } } }
  13. Build configuration kotlin { android() listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach

    { it.binaries.framework { baseName = "base" } } sourceSets { val commonMain by getting { dependencies { // … } } val commonTest by getting val androidMain by getting val androidTest by getting val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) } val iosX64Test by getting val iosArm64Test by getting val iosSimulatorArm64Test by getting val iosTest by creating { dependsOn(commonTest) iosX64Test.dependsOn(this) iosArm64Test.dependsOn(this) iosSimulatorArm64Test.dependsOn(this) } } } λʔήοτϓϥοτϑΥʔϜͷࢦఆ
  14. Build configuration kotlin { android() listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach

    { it.binaries.framework { baseName = "base" } } sourceSets { val commonMain by getting { dependencies { // implementation(…) } } val commonTest by getting val androidMain by getting val androidTest by getting val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) } val iosX64Test by getting val iosArm64Test by getting val iosSimulatorArm64Test by getting val iosTest by creating { dependsOn(commonTest) iosX64Test.dependsOn(this) iosArm64Test.dependsOn(this) iosSimulatorArm64Test.dependsOn(this) } } } ґଘؔ܎ͳͲͷઃఆ ※ ґଘ͢ΔϥΠϒϥϦଆͰɼ λʔήοτͱͳΔϓϥοτϑΥʔ ϜʹରԠ͍ͯ͠ͳ͍ͱ͍͚ͳ͍
  15. Build configuration kotlin { android() listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach

    { it.binaries.framework { baseName = "base" } } sourceSets { val commonMain by getting { dependencies { // implementation(…) } } val commonTest by getting val androidMain by getting val androidTest by getting val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) } val iosX64Test by getting val iosArm64Test by getting val iosSimulatorArm64Test by getting val iosTest by creating { dependsOn(commonTest) iosX64Test.dependsOn(this) iosArm64Test.dependsOn(this) iosSimulatorArm64Test.dependsOn(this) } } } ϥΠϒϥϦͷґଘؔ܎ ※ commonͰґଘ͍ͯ͠ΔϥΠϒ ϥϦ͕֤ϓϥοτϑΥʔϜʹର Ԡ͍ͯ͠Ε͹ɼϓϥοτϑΥʔ ϜผʹґଘΛॻ͘ඞཁ͸ͳ͍
  16. Build configuration kotlin { android() listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach

    { it.binaries.framework { baseName = "base" } } sourceSets { val commonMain by getting { dependencies { // implementation(…) } } val commonTest by getting val androidMain by getting val androidTest by getting val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) } val iosX64Test by getting val iosArm64Test by getting val iosSimulatorArm64Test by getting val iosTest by creating { dependsOn(commonTest) iosX64Test.dependsOn(this) iosArm64Test.dependsOn(this) iosSimulatorArm64Test.dependsOn(this) } } } ιʔεηοτಉ࢜ͷґଘؔ܎
  17. Build configuration kotlin { android { compilations.all { kotlinOptions.jvmTarget =

    "1.8" } publishAllLibraryVariants() } ios { binaries.framework { baseName = "base" } } // ... } • ෳ਺λʔήοτͷγϣʔτΧοτ΋༻ҙ͞Ε͍ͯΔ • ios (iosArm64/iosX64) • tvos (tvosArm64/tvosX64) • watchOS (watchosArm32/watchosArm64/watchosX64) • xxxSimulatorArm64͸ݱঢ়ؚ·Ε͍ͯͳ͍
  18. Kotlin΍Kotlin MultiplatformΛ஌Δ • ެࣜυΩϡϝϯτ • ެࣜϒϩά • YouTubeνϟϯωϧ • Slack

    • Twitter • reddit • ϋϯζΦϯ • αϯϓϧϓϩδΣΫτ • …
  19. Kotlin΍Kotlin MultiplatformΛ஌Δ • ެࣜυΩϡϝϯτ • ެࣜϒϩά • YouTubeνϟϯωϧ • Slack

    • Twitter • reddit • ϋϯζΦϯ • αϯϓϧϓϩδΣΫτ • … • ެࣜυΩϡϝϯτ • ެࣜϒϩά • YouTubeνϟϯωϧ • Slack • Twitter • reddit
  20. Kotlin΍Kotlin MultiplatformΛ஌Δ • ެࣜυΩϡϝϯτ • ެࣜϒϩά • YouTubeνϟϯωϧ • Slack

    • Twitter • reddit • ϋϯζΦϯ • αϯϓϧϓϩδΣΫτ • … • ϋϯζΦϯ • αϯϓϧϓϩδΣΫτ
  21. • ͍͔ͭ͘ͷϓϥοτϑΥʔϜͰ͸UI·Ͱڞ௨Խ͕೉͍͠ • StableͰͳ͍ͷͰϓϩδΣΫτશମͷେ͖ͳมߋ͕ඞཁͱͳΔ৔߹͕͋Δ • Swiftͱͷޓ׵ੑͰਏ͍͜ͱ͕… • Kotlin/NativeͷϏϧυ͕࣌ؒ௕͍ • ίϛϡχςΟ͕·ͩൺֱతখ͍͔͞΋ʁ

    KEEP GOING https://github.com/dropbox/AffectedModuleDetector • Kotlin/NativeͷϏϧυ͕࣌ؒ௕͍ KMMͷ՝୊ͱকདྷੑ ABEMAͰ͸ɼdropbox/AffectedModuleDetectorΛ Kotlin MultiplatformͰར༻Ͱ͖ΔΑ͏ʹͯ͠ɼมߋӨڹ ͷ͋ΔϞδϡʔϧͷΈΛϏϧυ͍ͯ͠Δ
  22. Hierarchical Project Structure • ϓϥοτϑΥʔϜͷιʔεηοτΛ·ͱΊΔ͜ͱ͕Մೳʹ • Kotlin 1.4.0͔ΒಋೖՄೳ • Kotlin

    1.6.20͔Β৽نϓϩδΣΫτ࡞੒ͷࡍʹσϑΥϧτͰઃఆ͞ΕΔΑ͏ʹ commonMain androidMain iosArm64Main iosX64Main commonMain androidMain iosArm64Main iosX64Main iosMain No Hierarchical Hierarchical https://kotlinlang.org/docs/multiplatform-hierarchy.html
  23. Kotlin/Native Memory Management • ݻ༗ͷϧʔϧ • ϧʔϧ1ɿMutable State == 1

    thread • ϧʔϧ2ɿImmutable State == many thread • Immutable State != val • ϥϯλΠϜͰෆมͳঢ়ଶʢfrozen stateʣͰ͋Δ͜ͱ͕ٻΊΒΕΔ • freeze()Ͱ͋ΒΏΔΠϯελϯεΛfreezeͰ͖Δ https://kotlinlang.org/docs/multiplatform-mobile-concurrency-overview.html Kotlin/NativeͷϚϧνεϨουϓϩάϥϛϯάͷ՝୊
  24. Kotlin/Native Memory Management • ղܾࡦ • AtomicXxxΛ࢖༻͢Δ • Thread-isolate stateΛ࢖༻͢Δ

    ImmutableͰͳ͍ͱෳ਺εϨουͰѻ͑ͳ͍ʁ https://kotlinlang.org/docs/multiplatform-mobile-concurrent-mutability.html
  25. New Kotlin/Native Memory Management • Reference-counting GC → Tracing GC

    ※ ࠓޙΞϧΰϦζϜ͕มΘΔՄೳੑ΋͋Δ • ฒߦͰͷGC͕Մೳʹ • freeze()͕ෆཁʹͳΔ • AtomicReference͸Ҿ͖ଓ͖ඞཁ • AtomicReferenceΛؚΜͩ॥؀ࢀরʹΑΔϝϞϦϦʔΫͷ৺഑͸ແ͘ͳͬͨ • Kotlin 1.6.20͔ΒexperimentalͳNew Memory Manager͕࢖༻Մೳ • GCͷύϑΥʔϚϯεʹ·ͩ໰୊͋Γ • Kotlin 1.7.0Ͱalphaʹ New Memory ManagementͰͲ͏ͳΔ͔ https://blog.jetbrains.com/kotlin/2021/05/kotlin-native-memory-management-update/
  26. New Kotlin/Native Memory Management • ϚΠάϨʔγϣϯΨΠυ • https://github.com/JetBrains/kotlin/blob/master/kotlin-native/NEW_MM.md • ϥΠϒϥϦ

    • kotlinx.coroutines • 1.6.0Ҏ߱ɼnative-mtόʔδϣϯΛ࢖༻͠ͳͯ͘ྑ͘ͳΔ • ktor • 2.0.0Ҏ߱͸New memory managementʹରԠ͢Δඞཁ͕͋Δ New Memory ManagementΛࢼ͢