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

Embracing commonMain for Android Development - Droidcon SF 2022

Embracing commonMain for Android Development - Droidcon SF 2022

We are all excited to use Kotlin Multiplatform, but on large projects it’s hard to figure out where to start using it without introducing risk. In this talk, I’ll give you techniques to start writing your code in commonMain right now. The code you write in commonMain is just Kotlin code, so it’s no different than what you write today, but with some slightly different configuration and guidelines that need to be followed. I’ll show you how to quickly set up your project configuration, and what guidelines to follow so you can start exercising your Multiplatform muscles. Writing code in commonMain helps promote modularity, and makes you think like a “Mobile developer” instead of just an “Android” developer.

5701f31a8433a22ae736282de8d08cd6?s=128

Sam Edwards

June 03, 2022
Tweet

More Decks by Sam Edwards

Other Decks in Programming

Transcript

  1. Sam Edwards - @HandstandSam Kotlin & Android GDE @ Dropbox

    Embracing commonMain 🫂 for Android Development Droidcon SF 2022
  2. KotlinMultiplatform for Android Development

  3. 🤔 https://dropbox.tech/mobile/the-not-so-hidden-cost-of-sharing-code-between-ios-and-android

  4. “By writing code in a non-standard fashion, we took on

    overhead that we would have not had to worry about had we stayed with the widely used platform defaults. This overhead ended up being more expensive than just writing the code twice.”
  5. The Overhead of: 1. Custom frameworks and libraries 2. Custom

    development environment 3. Addressing di ff erences between the platforms 4. Training, hiring, and retaining developers
  6. Kotlin Multiplatform? When Will You Use

  7. If/when it happens, it’ll be ORGANIC 🌱 ¯\_(ツ)_/¯

  8. Plant a seed for Kotlin Multiplatform 🌱 and we’ll see

    where it takes us • Same Kotlin Code, di ff erent Gradle plugin • Forces modularity • Makes developers more likely to try coding in the other platform
  9. What’s the Cost?

  10. Small Investment, Low Risk, …

  11. The Ultimate Source Set for Kotlin Multiplatform (KMP) commonMain

  12. None
  13. None
  14. commonMain

  15. JVM main Kotlin Compiler org.jetbrains.kotlin.android Plugin

  16. JVM main Kotlin Compiler org.jetbrains.kotlin.jvm Plugin

  17. JVM commonMain Kotlin Compiler org.jetbrains.kotlin.multiplatform Plugin

  18. JVM commonMain Kotlin Compiler org.jetbrains.kotlin.multiplatform Plugin JS iOS

  19. Plugins Kotlin + Gradle

  20. Kotlin + Gradle • kotlin(“android“) • kotlin(“jvm“) • kotlin(“multiplatform“) Plugins

    main main commonMain
  21. main and test Kotlin + Gradle dependencies { api(project(“:sample:module1”)) implementation(project(“:sample:module2"))

    testImplementation(libs.kotlin.test.common) }
  22. main and test Kotlin + Gradle dependencies { api(project(“:sample:module1”)) implementation(project(“:sample:module2"))

    testImplementation(libs.kotlin.test.common) }
  23. main and test Kotlin + Gradle dependencies { api(project(“:sample:module1”)) implementation(project(“:sample:module2"))

    testImplementation(libs.kotlin.test.common) }
  24. main and test Kotlin + Gradle dependencies { api(project(“:sample:module1”)) implementation(project(“:sample:module2"))

    testImplementation(libs.kotlin.test.common) }
  25. main and test Kotlin + Gradle dependencies { api(project(“:sample:module1”)) implementation(project(“:sample:module2"))

    testImplementation(libs.kotlin.test.common) }
  26. commonMain and commonTest Con fi gurations Kotlin + Gradle kotlin

    { jvm() sourceSets { maybeCreate("commonMain").apply { dependencies { implementation(libs.kotlin.coroutines) } } maybeCreate("commonTest").apply { dependencies { implementation(libs.kotlin.test.common) implementation(libs.kotlin.test.annotations.common) } } } }
  27. commonMain and commonTest Con fi gurations Kotlin + Gradle kotlin

    { jvm() sourceSets { maybeCreate("commonMain").apply { dependencies { implementation(libs.kotlin.coroutines) } } maybeCreate("commonTest").apply { dependencies { implementation(libs.kotlin.test.common) implementation(libs.kotlin.test.annotations.common) } } } }
  28. commonMain and commonTest Con fi gurations Kotlin + Gradle kotlin

    { jvm() sourceSets { maybeCreate("commonMain").apply { dependencies { implementation(libs.kotlin.coroutines) } } maybeCreate("commonTest").apply { dependencies { implementation(libs.kotlin.test.common) implementation(libs.kotlin.test.annotations.common) } } } }
  29. commonMain and commonTest Con fi gurations Kotlin + Gradle kotlin

    { jvm() sourceSets { maybeCreate("commonMain").apply { dependencies { implementation(libs.kotlin.coroutines) } } maybeCreate("commonTest").apply { dependencies { implementation(libs.kotlin.test.common) implementation(libs.kotlin.test.annotations.common) } } } }
  30. commonMain and commonTest Con fi gurations Kotlin + Gradle kotlin

    { jvm() sourceSets { maybeCreate("commonMain").apply { dependencies { implementation(libs.kotlin.coroutines) } } maybeCreate("commonTest").apply { dependencies { implementation(libs.kotlin.test.common) implementation(libs.kotlin.test.annotations.common) } } } }
  31. commonMain and commonTest Con fi gurations Kotlin + Gradle kotlin

    { jvm() sourceSets { maybeCreate("commonMain").apply { dependencies { implementation(libs.kotlin.coroutines) } } maybeCreate("commonTest").apply { dependencies { implementation(libs.kotlin.test.common) implementation(libs.kotlin.test.annotations.common) } } } }
  32. Run Anywhere* Write Once * Yes, but…

  33. Multiplatform is Still Under Development https://blog.jetbrains.com/kotlin/2022/05/kotlin-multiplatform-mobile-beta-roadmap-update/

  34. Compiling Multiplatform Can Be Slow https://medium.com/yazio-engineering/speeding-up-kotlin-multiplatform-61ebf8dae560 grade.properties

  35. Multiplatform Doesn’t Support Con fi guration Caching (Yet) https://youtrack.jetbrains.com/issue/KT-49933/Support-Gradle-Con fi

    guration-caching-with-HMPP
  36. Multiplatform Plugin Adds Overhead 7 Tasks 14 Tasks

  37. To Use Multiplatform with Zero Risk What Can We Do?

  38. Initial Proof of Concept https://github.com/handstandsam/ShoppingApp/pull/42

  39. Doesn’t Quite Work in Android Studio https://issuetracker.google.com/issues/229628556

  40. None
  41. kmp4free

  42. JVM Project Structure plugins { kotlin("jvm") } dependencies { implementation(libs.kotlin.stdlib)

    implementation(project(":samples:jvm_kmp4free")) testImplementation(libs.kotlin.test.common) testImplementation(libs.truth) }
  43. JVM Project Structure plugins { id("com.handstandsam.kmp4free") } dependencies { implementation(libs.kotlin.stdlib)

    implementation(project(":samples:jvm_kmp4free")) testImplementation(libs.kotlin.test.common) testImplementation(libs.truth) }
  44. Enable/Disable with Property # gradle.properties kmp4free=true or ./gradlew … -Pkmp4free=true

  45. JVM Project Structure

  46. JVM Project Structure

  47. JVM Project Structure kmp4free=false

  48. JVM Project Structure kmp4free=true kmp4free=false

  49. JVM Project Structure kmp4free=true kmp4free=false

  50. JVM Project Structure kmp4free=true kmp4free=false

  51. Source Set and Con fi guration Mapping How?

  52. Primary Goals of kmp4free • No Risk, Single Line Change

    to Enable Multiplatform • Support JVM & Multiplatform Con fi g • Allow Experimentation and Possible Migration to Multiplatform
  53. kmp4free=true • SourceSet Mapping • src/main ➡ src/commonMain • src/test

    ➡ src/jvmTest • Con fi guration Mapping • implementation ➡ commonMainImplementation • testImplementation ➡ jvmTestImplementation • Task Aliasing • :module:test ➡ :module:jvmTest
  54. kmp4free=false • SourceSet Mapping • src/commonMain ➡ src/main • src/jvmMain

    ➡ src/main • src/commonTest ➡ src/test • src/jvmTest ➡ src/test • Con fi guration Mapping • commonMainImplementation ➡ implementation • commonTestImplementation ➡ testImplementation • jvmTestImplementation ➡ testImplementation
  55. Migrating to commonMain com.android.library kotlin(“jvm”) kotlin(“multiplatform”) 
 commonMain

  56. Migrating tests from androidTest ➡ jvm androidTest (instrumented) test (jvm)

    • Does not require any devices • Faster (usually)
  57. Demo!

  58. KMP4FREE 🆓 is a low risk way to explore Kotlin

    Multiplatform
  59. No. Is it REALLY 🆓?

  60. Test and Experiment ♻ • Create a multiplatform app that

    exercises it.
  61. Thank You Dropbox is Hiring!