Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Strategies for Migrating to Jetpack Compose
Search
Mohit S
April 19, 2022
Programming
2
530
Strategies for Migrating to Jetpack Compose
Mohit S
April 19, 2022
Tweet
Share
More Decks by Mohit S
See All by Mohit S
Guide to Improving Compose Performance
heyitsmohit
0
200
Building Shared UIs across Platforms with Compose
heyitsmohit
1
590
Building Multiplatform Apps with Compose
heyitsmohit
2
450
Building StateFlows with Jetpack Compose
heyitsmohit
6
1.8k
Building Android Testing Infrastructure
heyitsmohit
1
430
Migrating to Kotlin State & Shared Flows
heyitsmohit
1
750
Using Square Workflow for Android & iOS
heyitsmohit
1
400
Building Android Infrastructure Teams at Scale
heyitsmohit
3
300
Challenges of Building Kotlin Multiplatform Libraries
heyitsmohit
1
420
Other Decks in Programming
See All in Programming
CRE Meetup!ユーザー信頼性を支えるエンジニアリング実践例の発表資料です
tmnb
0
350
SideKiqでジョブが二重起動した事象を深堀りしました
t_hatachi
0
230
AIエージェントを活用したアプリ開発手法の模索
kumamotone
1
750
AtCoder Heuristic First-step Vol.1 講義スライド(山登り法・焼きなまし法編)
takumi152
3
980
List とは何か? / PHPerKaigi 2025
meihei3
0
550
私の愛したLaravel 〜レールを超えたその先へ〜
kentaroutakeda
12
3.5k
PHPでお金を扱う時、終わりのない 謎の1円調査の旅にでなくて済む方法
nakka
3
1.2k
Firebase Dynamic Linksの代替手段を自作する / Create your own Firebase Dynamic Links alternative
kubode
0
180
なぜselectはselectではないのか
taiyow
2
310
Coding Experience Cpp vs Csharp - meetup app osaka@9
harukasao
0
110
Django for Data Science (Boston Python Meetup, March 2025)
wsvincent
0
240
アーキテクトと美学 / Architecture and Aesthetics
nrslib
12
3.1k
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
21k
YesSQL, Process and Tooling at Scale
rocio
172
14k
Bash Introduction
62gerente
611
210k
Being A Developer After 40
akosma
90
590k
Become a Pro
speakerdeck
PRO
27
5.2k
GitHub's CSS Performance
jonrohan
1030
460k
Java REST API Framework Comparison - PWX 2021
mraible
29
8.5k
The Pragmatic Product Professional
lauravandoore
33
6.5k
Unsuck your backbone
ammeep
670
57k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Building a Modern Day E-commerce SEO Strategy
aleyda
39
7.2k
Transcript
Mohit Sarveiya Strategies for Migrating to Jetpack Compose @heyitsmohit
Strategies for Migrating to Jetpack Compose • Challenges • How
to think about migration • Strategies & Tools
Challenges
Code size Code size Time
Greenfield Project • Easier to use Compose • Fewer roadblocks
to use Compose
Code size Code size Time
Roadmap 0% Compose 100% Compose
Roadmap 0% Compose 100% Compose Roadblock Roadblock
Roadmap • Long road • Obstacles along the way
Arch Fragmentation Codebase
Arch Fragmentation Codebase Legacy code
Arch Fragmentation Codebase Legacy code Feature A Feature B
Challenges • Interoperability
Interop • Compose to old view system
Interop Codebase Feature A Compose View Legacy code
Interop Codebase Legacy code Feature A Compose View
Interop • Compose to old view system • Use old
views in Compose
Interop Codebase Legacy code Feature A Custom View
Interop Codebase Feature A Compose with Custom View Legacy
code
Challenges • Interoperability • Architecture
Architecture Codebase Legacy code
Arch Challenges • Not using composition over inheritance
Legacy Code Base Fragment Too much logic
Legacy Code Base Fragment Too much logic Fragment Fragment Fragment
…
Legacy Code Base Fragment Fragment Fragment Fragment … Refactor to
Compose
Legacy Code Base View Holders Too much logic
Legacy Code Base View Holders Too much logic View Holder
View Holder View Holder … Refactor to Compose
Arch Challenges • Not using composition over inheritance • Navigation
App Architecture API Domain Navigation UI
Navigation NavHost(navController, startDestination = "profile") { composable("profile") { Profile( /*...*/
) } composable("friendslist") { FriendsList( /*...*/ ) } }
Legacy Navigation Main Activity Activity Activity
Navigation Main Activity Fragment A Fragment B Fragment C ...
Challenges • Interoperability • Architecture • Testing
Testing Codebase 1% Code coverage 5% Code coverage
Challenges • Interoperability • Architecture • Testing • Tooling
Compose Upgrades Version Time alpha05 alpha06
Challenges • Interoperability • Architecture • Testing • Tooling
Collaboration Org CI Arch Design Team Feature Teams Teams
Strategies
Roadmap 0% Compose 100% Compose
Roadmap 0% Compose 100% Compose Milestone Milestone
Proposal • Specify milestones over time • Assess & Mitigate
Risks • Documentation
Roadmap 0% Compose 100% Compose Milestone
Complexity Codebase High Low Medium
Migration Phase 1 Complexity Migration time Low
Migration Phase 2 Complexity Migration time Medium
Migration Phase 1 • Migrate Design Components
Example Feature A Feature B Feature C Common Design
Components
Example Common Design Components App A App B App
C
Collaboration Org CI Arch Design Team Feature Teams Teams
Migration Phase 1 • Migrate design components to Compose
Interoperability
Interop 9:41
Interop 9:41 Convert to compose
Interop <ConstraintLayout> <ImageView /> <Button /> <TextView /> <TextView />
</ FrameLayout> 9:41
Interop <ConstraintLayout> <ImageView /> <Button /> <TextView /> <TextView />
</ FrameLayout> 9:41
Interop <ConstraintLayout> <ImageView /> <Button /> <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="wrap_content"
/> </ FrameLayout>
Compose View binding.composeView.apply { setContent { } }
Compose View binding.composeView.apply { setContent { MaterialTheme { DescriptionView() }
} }
Challenges strings.xml dimen.xml theme.xml Compose Resuse
Compose View @Composable fun DescriptionView() { Text( text = stringResource(id
= R.string.title) ) }
Compose View @Composable fun DescriptionView() { Text( modifier = Modifier.padding(dimensionResource(R.id.margin_small))
) }
Challenges • How do you reuse dimen and string resources?
• Interop Theming
Challenges strings.xml dimen.xml theme.xml Compose Resuse
Interop Theming implementation “com.google.android.material:compose-theme-adapter:1.1.1”
Interop Theming binding.composeView.apply { setContent { MaterialTheme { DescriptionView() }
} }
Interop Theming binding.composeView.apply { setContent { MdcTheme { DescriptionView() }
} }
Challenges • How do you reuse dimen and string resources?
• Interop Theming • View lifecycle
Compose View binding.composeView.apply { setContent { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) }
}
Phase 1 Migration Common Design Components App A App
B App C
Common Design Components • View all compose components • Document
design system
airbnb/Showkase Code ! Issues Pull Requests Showkase Compatible with Compose
1.0.4 Showcase 1.0.0-beta12 Showkase is an annotation-processor based Android library that helps you organize, discover, search and visualize Jetpack Compose UI elements.
Showkase 9:41 App com.app General Logs Other Keyline overlay Slow
down animations Network Activity Logs Lifecycle logs Show UX
Showkase 9:41 App com.app General Logs Other Keyline overlay Slow
down animations Network Activity Logs Lifecycle logs Show UX 9:41 Design Components Components Colors Typography
Showkase Compose Design Spec Generate
Showkase @ShowkaseRoot class AppRootModule: ShowkaseRootModule
Showkase startActivity(Showkase.getBrowserIntent(this))
Showkase @Preview(name = “Custom component", group = "Custom group") @Composable
fun PostView()
Showkase 9:41 Design Components Post view Title
Arch Fragmentation Codebase Legacy code 100% Compose 100% Compose
Interop @Composable fun PostView() { AndroidView(factory = { context ->
})
Interop @Composable fun PostView() { AndroidView(factory = { context ->
CustomView(context).apply { layoutParams = LinearLayout.LayoutParams( MATCH_PARENT, WRAP_CONTENT ) } })
Interop • ComposeView • AndroidView
Migration Phase 1 • Migrate Design Components
Roadmap 0% Compose 100% Compose Milestone
Roadmap 0% Compose 100% Compose Milestone Milestone
Migration Phase 2 Complexity Migration time Medium
Testing Codebase 1% Code coverage 5% Code coverage
Migration Phase 2 • Migrate medium complexity features • Setup
scaffolding to catch regressions
Testing
Testing Infra Compose Conversions Testing Infra
Goals • Catch regressions earlier • Increase covers with compose
migration
Testing Infra • Snapshot testing • UI Testing Interop
cashapp/paparazzi Code ! Issues Pull Requests Paparazzi An Android library
to render your application screens without a physical device or emulator.
Paparazzi Screenshot Unit Test
Paparazzi • 1.0.0-Snapshot has compose support
Paparazzi @get:Rule val paparazzi = Paparazzi()
Paparazzi @get:Rule val paparazzi = Paparazzi() @Test fun testView() {
paparazzi.snapshot { PostView(uiState) } }
Paparazzi 9:41 Post Title
Paparazzi Git (LFS) Snapshot
Testing Infra • Snapshot testing • UI Testing Interop
Interop <ConstraintLayout> <ImageView /> <Button /> <ComposeView /> </ FrameLayout>
9:41
Interop 9:41 Semantics Tree
Compose UI Testing @get:Rule val composeTestRule = createAndroidComposeRule<MainActivity>()
Compose UI Testing @Test fun postViewTest() { composeTestRule.onNodeWithText(“Title").assertIsDisplayed() }
Interop @Composable fun PostView() { AndroidView(factory = { context ->
CustomView(context) }) }
Interop @Test fun postViewTest() { composeTestRule.onNodeWithText("Submit").performClick() }
Interop @Test fun postViewTest() { composeTestRule.onNodeWithText(“Submit").performClick() Espresso.onView(withText(“Success")).check(matches(isDisplayed())) }
Migration Phase 2 • Migrate medium complexity features • Setup
scaffolding to catch regressions
Migration Phases 0% Compose Milestones
Migration Phases • Milestones depend on complexity & code size
• Low Complexity -> High Complexity
Migration Phases 0% Compose Milestones Testing Infra
Internationalization
Migration Phases 0% Compose Milestones
Languages Support strings.xml values-en values-de values-fr strings.xml strings.xml
Languages Support Add strings
Languages Support Translation service Add strings
Languages Support Translation service Provides translated strings Add strings
Languages Support • Compose language interop
adrielcafe/lyricist Code ! Issues Pull Requests Lyricist The missing I18N
and L10N multiplatform library for Jetpack Compose!
Languages Support Strings (xml) Types KSP Composition Local
Languages Support strings.xml values values-pt strings.xml
Languages Support <resources> <string name=“greeting”>Hello world </ string> <string-array name="array">
<item>Avocado </ item> </ string-array> <plurals name="plurals"> <item quantity="zero">%d zero </ item> </ plurals> </ resources>
Languages Support <resources> <string name=“greeting”>Olá mundo </ string> <string-array name="array">
<item>Abacate </ item> </ string-array> <plurals name="plurals"> <item quantity="zero">%d zero </ item> </ plurals> </ resources>
Languages Support ksp { arg("lyricist.xml.resourcesPath", android.sourceSets.main.res.srcDirs.first().absolutePath) arg("lyricist.xml.moduleName", “xml") arg("lyricist.xml.defaultLanguageTag",
"en") }
Languages Support data class Strings( val greeting: String, val array:
List<String>, val plurals: (quantity: Int) -> String ) object Locales { val En = "en" val Pt = "pt" }
Languages Support @Composable public fun <T> ProvideStrings() { CompositionLocalProvider( provider
provides lyricist.strings ) }
Languages Support @Preview @Composable fun PostViewPreview() { val xmlStrings =
rememberXmlStrings() ProvideXmlStrings(xmlStrings) { Text(text = xmlStrings.greeting) } }
Languages Support @Preview @Composable fun PostViewPreview() { val xmlStrings =
rememberXmlStrings() ProvideXmlStrings(xmlStrings) { Text(text = xmlStrings.greeting) } }
Languages Support @Preview @Composable fun PostViewPreview() { val xmlStrings =
rememberXmlStrings() ProvideXmlStrings(xmlStrings) { Text(text = xmlStrings.greeting) } }
Languages Support @Preview @Composable fun PostViewPreview() 9:41 Post Hello World
Languages Support @Preview(locale = “pt”) @Composable fun PostViewPreview() 9:41 Post
Olá mundo
Migration Phases 0% Compose Milestones
Tooling
Kotlin Upgrades This version (1.1.1) of the Compose Compiler requires
Kotlin version 1.6.10 but you appear to be using Kotlin version 1.6.20 which is not known to be compatible.
Kotlin Upgrades composeOptions { kotlinCompilerExtensionVersion compose_version suppressKotlinVersionCompatibilityCheck true
} Not Recommended
Kotlin Upgrades • Wait for compose to be updated
None
Kotlin Upgrades • Wait for compose to be updated •
Test out compose upgrades
None
Kotlin Upgrades • Wait for compose to be updated •
Test out compose upgrades
Strategies for Migrating to Jetpack Compose • Challenges • How
to think about migration • Strategies & Tools
Thank You! www.codingwithmohit.com @heyitsmohit