JetpackCompose.app's Dispatch Issue #7

šŸ’Œ In today's issue, we discuss the šŸ¦ƒ that broke your code, learn from Saket Narayan, cover some personal wins, and talk about safeguarding composables

Whatā€™s the status of the release?
Whatā€™s the status of the release?
Whatā€™s the status of the release?
Whatā€™s the status of the release?

Tired of answering the same questions every time you ship an update?

GM 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.

Saket Narayan

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 using Cmd+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 browsing r/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).

šŸ‘‚ 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

or to participate.