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
480
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
110
Building Shared UIs across Platforms with Compose
heyitsmohit
1
450
Building Multiplatform Apps with Compose
heyitsmohit
2
390
Building StateFlows with Jetpack Compose
heyitsmohit
6
1.7k
Building Android Testing Infrastructure
heyitsmohit
1
360
Migrating to Kotlin State & Shared Flows
heyitsmohit
1
650
Using Square Workflow for Android & iOS
heyitsmohit
1
350
Building Android Infrastructure Teams at Scale
heyitsmohit
3
270
Challenges of Building Kotlin Multiplatform Libraries
heyitsmohit
1
380
Other Decks in Programming
See All in Programming
文化が生産性を作る
jimpei
2
500
クラウドサービスの 利用コストを削減する技術 - 円安の真南風を感じて -
pyama86
3
240
Cloud Adoption Framework にみる組織とクラウド導入戦略
tomokusaba
2
200
5年分のツケを一気に払った話
soogie
3
1.1k
C#および.NETに対する誤解をひも解く
ymd65536
0
230
フロントエンドの標準仕様をどう追っているか / How I follow the frontend standards specs
petamoriken
2
170
Beyond the RuboCop Defaults
koic
2
480
Removing Corepack
yosuke_furukawa
PRO
9
1.1k
Cancel Next.js Page Navigation: Full Throttle
ypresto
1
110
M5Stackボードの選び方
tanakamasayuki
0
200
Интеграционное тестирование: как приручить хаос
mariyasaygina
0
480
CSC509 Lecture 01
javiergs
PRO
1
200
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
79
8.6k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
504
140k
We Have a Design System, Now What?
morganepeng
49
7.1k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
41
9.2k
The Straight Up "How To Draw Better" Workshop
denniskardys
231
130k
Design by the Numbers
sachag
278
19k
Designing the Hi-DPI Web
ddemaree
279
34k
Agile that works and the tools we love
rasmusluckow
327
21k
Building Better People: How to give real-time feedback that sticks.
wjessup
360
19k
It's Worth the Effort
3n
183
27k
Become a Pro
speakerdeck
PRO
24
4.9k
Infographics Made Easy
chrislema
239
18k
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