Dispatch Issue # 7
Good Morning Friends! This is JetpackCompose.appās Dispatch. The Android/Jetpack Compose newsletter thatās more refreshing than jumping into a pool on a scorching summer day.
I want to start off by acknowledging that this issue took a little longer to hit your inbox, but trust me, itās for a good reason. I've been cooking up some exciting things behind the scenes that are going to make their way into the newsletter soon. Letās just call it an investment in making my subscribers (thatās you!) even happier š
š£ Personal Update
In action during the Fireside Chat at Googleās internal conference for their mobile engineering teams
To kick things off, I wanted to share a quick personal āWā. A few weeks ago, I had the incredible honor of being invited by Google for a Fireside Chat at one of their internal conferences - Mobile Week, that aims to bring together mobile engineers at Google (and thereās thousands of them).
Now, Iāve been doing this whole conference-speaking thing for almost 10+ yearsāconferences, meetups, private events, you name it. But this one? It hit different. It felt like a real career milestoneāa full-circle moment, especially since so much of my professional journey has been built on top of Android. It was one of those moments where you stop and think, "Wow, how did I get here?". Iām just really grateful for the opportunity šš»
š¤¬ WTFacts
Why toUpperCase()
Got the Boot?
We are all familiar with this strikethrough warning every time we try to use functions like toUpperCase and toLowerCase. Ever wondered why these functions got the boot in the first place? Blame it onā¦Turkey š¦ No, not that kind š¤¤ I mean Turkey, the country š¹š· More specifically, itās the turkish language we are talking about.
Turns out, uppercase and lowercase letters don't play by the same rules everywhere. In English, uppercase "i" is "I" (duh), but in the Turkish language, it's "Ä°" (with a dot on top!).
Turkish Letters
This tiny difference can cause major chaos. Since toUpperCase
relied on Locale.getDefault()
, your code could behave differently depending on where you are. To fix this, Kotlin swapped it out for uppercase(Locale.ROOT)
for consistency. The same deal goes for lowercase
. Well now you know why you need to see that yellow strikethrough line on a daily basis š
š Dev Delight
š¤ Interesting tid-bits
Iterate in SQL, not in code
If you're still looping over SQL queries in your code, we need to talk š¤Ø Instead of running a loop to fetch individual results, use a single query to get everything in one go. Now this doesnāt sound genius by any means and most of us couldāve figured this out ourselves. But what forced me to stop was the fact that the official documentation states that running the loop is roughly 1000 times slower than a well-crafted SQL query!!!!
The slow way:
val ids = listOf(1, 2, 3, 4)
val results = mutableListOf<Data>()
ids.forEach { id ->
val result = database.query("SELECT * FROM data WHERE id = $id")
results.add(result)
}
The fast way:
SELECT * FROM data WHERE id IN (1, 2, 3, 4)
See the difference? One query vs. multiple round trips to the database. The latter will have your app running like it just drank a gallon of espresso.
When you look at this example, it seems super obvious. However, when there are numbers like 1000 times slower in the equation, it really forces you to rethink how you handle database queries. Time to let SQL do its thing š«”
Compose š¤ Generative AI, a match made in heaven
Compose is a dream come true for LLMsāpossibly by accident. Think about it: everything is self-contained in the same file, no more juggling between XML and code, making it easier for LLMs to parse and generate UI components in one go. The declarative syntax and reusable functions are perfectly aligned with how LLMs break down problems. Itās like Compose was secretly engineered for AI-driven development without even realizing it. Sure, it wasnāt designed with LLMs in mind, but it feels like the future of how we interact with AI-driven tools just happened to land right in Jetpack Composeās sweet spot.
This conversation was the inspiration behind this thought.
šš» Adios Context Receivers, Hola Context Parameters
Remember when Kotlin 1.6.20 brought us context receivers as an experimental feature? Well, after some heart-to-heart feedback from the community, Kotlinās moving on. Yep, context receivers are heading toward retirement. But donāt worry, Kotlin isnāt leaving us hanging. Instead, say hello to context parameters, coming in future releases! Since context receivers were used by quite a few of us already (not me thankfully), Kotlinās making sure the removal process is smooth. Starting in Kotlin 2.0.20-RC2, youāll get gentle nudgesāaka warningsāif youāve been using them with the -Xcontext-receivers option. So, no panic required, just a heads-up that change is on the horizon.
š„ Tipsy Tip
Preventing a Composable Function from Being Invoked During Composition:
In Jetpack Compose, it's important to ensure that certain functions arenāt invoked during the composition phase to avoid side effects or performance issues. The composition phase is when the UI is built, and invoking functions hereāespecially those that modify stateācan lead to unpredictable behavior.
If side-effect-heavy functions are called during composition, it could cause multiple unintended invocations. While React uses strict mode to intentionally double-render components and catch these issues, Jetpack Compose doesnāt yet have a similar feature.
You can use custom lint rules to ensure certain functions (like your analytics utilities for example) arenāt called during composition. Compose already includes some rules that prevent misuse of coroutines, like ensuring launch
or async
is wrapped in LaunchedEffect
. You can create your own rules following this patternācheck out this example for inspiration.
š©āš» Featured Developer
This issueās featured developer is the brilliant Saket Narayan, an engineer at Block working on Cash App, renowned for creating elegant interactions and pushing Android to do things that few others can achieve.
Whatās your favorite Android Studio shortcut?
Ctrl+G
for sure. It makes me feel like a god while refactoring large blocks of code. I also love usingCmd+Shift+A
for searching through actions whose shortcuts I havenāt memorized yet.
You are well regarded for building apps and libraries with remarkable attention to detail. Where do you think your passion for it comes from?
Iāve often wondered about this myself. It might stem from my love for art, as I used to oil paint when I was younger. It could also be due to the fact that Android doesnāt have as many high-quality apps as iOS, so thereās a huge opportunity for developers to fill this space.
Your work on libraries such as Telephoto, Swipe, Dank, etc requires you to do Math. What resources would you recommend for someone that wants to pick up these āgraphic programmingā related concepts.
If anyone would benefit from those books the most, it would be me. I struggle with math and curse myself for not paying more attention in coordinate geometry classes during school.
Iāve had times where Iāve spent the entire day trying to figure things out, but eventually brute-forced my way out of it.
I am not smart. I just happen to be very persistent.
Where do you get your inspiration from when it comes to good design?
Iām a fan of Androidās system UI. For example, I love the shared element transitions in the quick settings tiles.
For design inspiration, I browse Dribbble and BeautifulPixels. Pttrns and mobbin.design are also great resources, but theyāve become expensive for casual browsing.
Also, the apps by Sam Ruston are usually a work of art. Things, Paper, and even games such as Into the Breach are also good references.
Whatās once piece of advice youād give other developers?
I have increasingly seen a pattern of developers over-architecting their apps. Simple projects are divided into numerous layers in the name of clean architecture, which does more harm than good. This is definitely a larger discussion, but Iād like to ask developers to find pragmatism in their code design and prioritize actual customer experiences instead of obsessing over
UseCase
classes.
What's your daily driver?
Iām using a Pixel Fold that will soon be replaced with the Pixel 9 Fold. Iāve been a foldable user for many years and will likely continue to be one because of my love for weird phones.
Favorite purchase in the last year
Probably my car (Genesis GV70). I used to think I wasnāt a car person, but purchasing a car has changed my opinion. My wife and I are always finding excuses to go on long drives. It also helps that we live in a small city (Waterloo) where thereās barely any traffic.
If you were allowed only 3 apps on your phone, which apps would it be and why?
Zillow for window-shopping houses with my wife, especially the ones weāll never be able to afford in our lifetimes.
Instagram for finding and sending memes to my friends.
Boost for browsingr/aviation
,r/handbags
,r/cars
,r/bollywood
,r/waterloo
, and other similar subreddits.
One project that you feel most proud about shipping
Iāve shipped many OSS projects, but Telephoto has probably been the most satisfying one. I grew tired of the fact that building media viewers is a hard problem on Android and decided to solve it for everyone. Maintaining it is proving to be a challenge, however, because Iām relying on other developers to share their bug reports with me. Hereās an example issue where I had to print log statements in my exceptions with a link to share them with me.
Whatās your favorite feature in Jetpack Compose
For writing UIs, Iād vote for lazy layouts. I donāt want to go back to writing
RecyclerView
adapters anymore. For non-UI code, Iāve become a fan of writing my presenters using Compose (through Molecule). I used to be adamant about writing my presenters using reactive streams only, but Compose has made me realize that certain tasks are easier to code in an imperative fashion (e.g., retrying with an exponential backoff).
If you found this useful, please share it on your companyās Android specific Slack channel and/or your Twitter account. Your feedback is invaluable, and it helps me know that my efforts are making a difference. Otherwise, it feels like Iām shouting into the void!
On that note, hereās hoping that your bugs are minor and your compilations are error free.