- JetpackCompose.app Dispatch
- Posts
- JetpackCompose.app Dispatch Issue #3
JetpackCompose.app Dispatch Issue #3
š In today's edition, we discuss Server Composabes, new graphicsLayer API, visibility tracking, and debouncing state updates
Good Morning Friends! This is JetpackCompose.appās Dispatch, where we sort through important Android happenings like it's a clearance sale ā only the best bargains for your brain.
This is Issue # 3 and we have a bunch of very interesting topics for you to dive into š¤æ
š” Insider Insight
Remember those PR reviews where you schooled your peers on the lambda variant of the graphicsLayer API? You were the office hero, the Compose wizard, the one who brought performance enlightenment. Well, get ready to don your superhero cape again because thereās a new kid on the block: the rememberGraphicsLayer API.
The shiny new rememberGraphicsLayer API returns a Graphic Layers object that you can redirect draw commands to. Itās primarily designed for magical feats like converting a Composable to a Bitmap. This is incredibly useful for sharing screenshots for bug reports, sharing app content on social media, or simply impressing your friends.
val coroutineScope = rememberCoroutineScope()
val layer = rememberGraphicsLayer()
Box(
modifier = Modifier
.drawWithContent {
// The GraphicsLayer object exposes a record
// function to capture the content in the
// layer.
layer.record {
// draw the contents of the composable
// into the graphics layer
this@drawWithContent.drawContent()
}
// draw the graphics layer on the
// visible canvas
drawLayer(graphicsLayer)
}
.clickable {
coroutineScope.launch {
val bitmap = layer.toImageBitmap()
// do something with the newly
// acquired bitmap
}
}
.background(Color.White)
) {
Text(
"Thank you for reading Dispatch!",
fontSize = 26.sp
)
}
Look at that elegance! The new API is straightforward, requiring just a couple of lines of code to work its magic. But behind the scenes, the implementation was no small feat. Check out this intricate process at the framework level. Great APIs are like good butlersāthey handle all the complexity so you can focus on the finer things in life š¶
All the Pull Requests that went into enabling the new rememberGraphicsLayer API
š Dev Delight
@alex_vanyo FlowRow is definitely not used for the FlowRow documentation! š
ā Louis CAD (@Louis_CAD)
5:52 PM ā¢ Mar 2, 2024
Uhh Thank you..
#programmingjokes#programmingmemes#AndroidDev #Android#javascript#js#100DaysOfCode#memes#officeMeme#nodejs#SwiftUI#Apple#androidapp#Dev#code#Coding
ā mac (@mage1k99)
1:35 PM ā¢ May 10, 2021
š„ Tipsy Tip
In a previous edition, we mentioned that the Compose Compiler codebase moved to the Kotlin repo. This change brought a shiny new composeCompiler DSL that lets you configure various compiler options. Sounds great, right? Well, plot twist: this new DSL actually breaks Layout Inspector. š
But fear not, fellow devs, because Chris Banes is here to save the day. He shared a quick fix: just add the following compile option, and youāll be back in business. The DSL doesnāt include source information by default, which is crucial for the Layout Inspector to function properly.
composeCompiler {
includeSourceInformation.set(true)
}
Hopefully, this tip spares you a world of pain. If youāve tried using Kotlin 2.0, youāve likely encountered this issue.
š¤ Interesting tid-bits
Ever tried logging impressions of components or screens in your app when theyāre displayed to a user? If youāve been down that rabbit hole, you know itās like trying to catch the wind. I tackled this at Airbnb using the Modifier system, but having an out-of-the-box solution wouldāve been a time-saver, given how common this functionality is. The reason itās not a standard feature? Thereās a ton of nuance in defining what counts as an āimpression.ā
Enter Rebecca Franks, a Dev Rel Engineer at Google, whoās swooping in to save the day with a proposal for a new āVisibilityā Modifier. This nifty Modifier aims to track visibility changes of a Composable easily. Itās still a proposal because, like any good superhero, it has its kryptonite: performance implications when used in lists. But hey, itās currently the best way to track visibility, so I encourage you to check it out. And if youāve got opinions, suggestions, or just want to say hi, give Rebecca your feedback directly. Letās help shape this API -
At the recent KotlinConf, one announcement flew under the radar but could be a game-changer: kotlinx-rpc. Itās a first-party Kotlin library for adding asynchronous Remote Procedure Call (RPC) services to your apps. At first glance, it might not sound all that thrilling. However, Isuru Rajapakse quickly highlighted its potential to create React-style server componentsāor āServer Composables,ā if you will.
Imagine moving your app's business logic to the server. Isuru crafted a Proof of Concept using Squareās Molecule library to host Composables on the server, which then emit a StateFlow stream consumed by the client-side UI. This means you can use the same mental model for both UI and business logic while the logic lives on the server.
Pretty exciting, right? If youāre as intrigued as I am, you can check out his Proof of Concept in this Pull Request.
With kotlinx-rpc - you can create "Server Composables" and move your screen business logic to the server!
Here's a quick POC github.com/xxfast/Counterā¦
#KMP#Kotlinconf
ā Isuru Rajapakse (@IsuruKusumal)
2:28 PM ā¢ May 24, 2024
Google is shaking up documentation with a fresh format called āQuick Guides.ā These guides focus on very specific tasks you might want to accomplish, like āanimating character-by-character the appearance of textā or āstyling part of a text.ā Itās like a cheat sheet but cooler and more practical.
This new style is similar to some of my own projects like āLearn Jetpack Compose By Exampleā and āCompose Snippetsā so Iām thrilled to see Google hopping on this trend. It makes learning more hands-on and less like deciphering an ancient manuscript.
I highly recommend checking these Quick Guides out and giving them a solid bookmark. With any luck, Google will keep adding new ones frequently.
Quick guides are a new type of documentation for Android developers
One of the quirks of using Composables like FlowRow/Column is their lack of optimization for a large number of child elements. These traditional flow components render all items, regardless of their visibility, which can be a performance drag. To address this, Google introduced ContextualFlowRow and ContextualFlowColumn in the 1.7.0-beta01 release. These components smartly limit composition to only visible items within constraints like maxLines or maxWidth. This ensures your app runs smoother by reducing the number of items composed based on the current context and display parameters.
But wait, thereās more! These new components also allow for contextual decisions, such as implementing overflow behavior with a āSee moreā button when the constraints are hit.ContextualFlowRow is useful for implementing a use-case like this where
From an API perspective, here are a couple of thoughts:Should this have been the default behavior for flow components? š¤ It seems logical to optimize from the get-go.
Itās curious that these components are in the
compose.foundation
package. They feel specific enough to belong in thecompose.material
package. While this is a minor nitpick, thereās a concern that the foundation packages might get bloated over time.
š» Code Corner
Todayās Code Corner shines a spotlight on a clever snippet shared by Pablisco. He shows us how to extend the MutableState interface to create custom behaviors. Specifically, he implemented a version of MutableState that debounces the state value if itās updated within a specified debounceTime.
As with many things in programming, thereās more than one way to achieve the same goal. Pablisco offers an alternative snippet that uses a custom SnapshotMutationPolicy to accomplish the same debouncing behavior. The main difference is that this approach uses the default mutableStateOf implementation with a custom mutation policy. Dive into the implementation and usage here:
Itās a great reminder that in coding, flexibility is key. Whether you choose to extend MutableState or use a custom mutation policy, youāve got options to tailor your state management to your needs.
š„ Media Player
I want to share a fascinating video with yāall that Iām confident you didnāt expect to see. While the video is primarily focused on JavaScript, the ideas itās presenting are valid even for the Compose ecosystem. In fact, the reason I stumbled on this video is because Jim Sproch, whoās one of the people to propose Jetpack Compose @ Google, recommended it in one of his tweet.
Hereās some more light on why he brought up this video -
I worked on product infrastructure at Facebook, where we interfaced with countless product teams, many of which were using Dependency Injection (DI) and others were not. This is where the more meta conclusions/understanding formalized in my mind. Cross cutting concerns were the source of problems. It was a consistent experience that cross cutting concerns (and DI in particular) made it very difficult to understand the impacts of small targeted changes. They are very difficult to unwind and refactor because they bury the complex behaviors that become implicitly assumed. One of my coworkers on React.js did an absolutely fantastic talk on the subject, which does a fantastic job of distilling these same findings; he independently arrived at the same conclusions, the talk is amazing.
Here, Jim was talking about how heās not a fan of Dependency Injection and even CompositionLocals because thatās also an implicit way of doing dependency injection in some ways. The talk doesnāt directly address this, however, it does dole out some good advice around abstractions, surface area of the language, etc.
š Let me hear it!
Whatād you think of this email? Tap your choice below and lemme hear it š
On that note, hereās hoping that your bugs are minor and your compilations are error free,
Reply