SUBSCRIBE NOW
avatar
I always learn something just by skimming it that makes me want to bookmark the issue now and dig deeper later
SUBSCRIBE NOW
avatar
Keep up the good work with the newsletter 💪 I really enjoy it
SUBSCRIBE NOW
avatar
Dispatch is a must read for Android devs today and my go-to for keeping up with all things Jetpack Compose
SUBSCRIBE NOW
avatar
Dispatch has been my go-to resource as it's packed with useful information while being fun at the same time
SUBSCRIBE NOW
avatar
The content is light, fun, and still useful. I especially appreciate the small tips that are in each issue
SUBSCRIBE NOW
avatar
I truly love this newsletter ❤️‍🔥 Spot on content and I know there's a lot of effort that goes behind it
SUBSCRIBE NOW
avatar
Thanks for taking the time and energy to do it so well
JetpackCompose.app's Newsletter
avatar
I always learn something just by skimming it that makes me want to bookmark the issue now and dig deeper later
JetpackCompose.app's Newsletter
avatar
Keep up the good work with the newsletter 💪 I really enjoy it
JetpackCompose.app's Newsletter
avatar
Dispatch is a must read for Android devs today and my go-to for keeping up with all things Jetpack Compose
JetpackCompose.app's Newsletter
avatar
Dispatch has been my go-to resource as it's packed with useful information while being fun at the same time
JetpackCompose.app's Newsletter
avatar
The content is light, fun, and still useful. I especially appreciate the small tips that are in each issue
JetpackCompose.app's Newsletter
avatar
I truly love this newsletter ❤️‍🔥 Spot on content and I know there's a lot of effort that goes behind it
JetpackCompose.app's Newsletter
avatar
Thanks for taking the time and energy to do it so well

Dispatch Issue # 9

🔥 JetBrains' project to bring true hot reload to Compose, share a tip to improve screenshot test reliability using a new CompositionLocal, explore situations when onDispose doesn't get called, and bid farewell to Picasso 👨🏻‍🎨
Vinay Gaba Profile Image
Vinay Gaba on November 30, 2024
Hero Image

Good Morning Friends. This is JetpackCompose.app’s Dispatch - we deliver interesting and entertaining content about Android and Jetpack Compose, guaranteed fresh, in 5 mins or less.

This is Issue # 9 and it’s been an exciting past few weeks of Android and Jetpack Compose updates.

🍾 Pop Quiz

Time to test those Compose savvy brains of yours!

Question:

Is the onDispose callback of the DisposableEffect side-effect guaranteed to be executed at some point? Is there any scenario in which it might not be executed at all?

val foo = remember { foo() }
DisposableEffect(foo) {
  onDispose {
    foo.dispose()
  }
}

Find the answer in a section below ⬇️

🤔 Interesting tid-bits

Imagine riding the subway in a new city, deep underground, with no GPS signal and spotty cell service. How do you know when your stop is coming up? Traditionally, you might rely on signage, announcements, or the kindness of strangers.

Well, the folks at Transit app have come up with a novel solution: providing underground directions without depending on GPS. 🧭

How did they do it?

The Transit team leveraged the phone's accelerometer and motion sensors to detect the movement patterns unique to subway trains. By collecting and analyzing vibration data from countless rides, they trained a machine learning model to predict:

  1. When you're on a moving train vs. standing still.
  2. The number of stops and estimated time between stations.

Transit app using sensor data to predit location

Using this data, the app can predict your current location within the tunnel , updating your ETA and guiding you to your stop—even without an internet connection.

Why is this noteworthy?

Instead of relying on GPS, which doesn't penetrate underground, they harnessed other sensors readily available on smartphones.

Kudos to the Transit team for thinking outside the GPS box! 📦

Farewell, Picasso! 🎨

Remember Picasso? No, not the painter with the funky cubism style, but the beloved Android image loading library that's been our companion for the better part of a decade. Picasso was the go-to library for image loading and caching in Android apps. It simplified image handling, reducing boilerplate code and preventing those dreaded OutOfMemoryError s. It was as trustworthy as your favorite pair of old sneakers.

Well, folks, it's official: Picasso has been deprecated.

The Android ecosystem evolved, and so did our tools. Coil and Glide have taken the spotlight, offering improved performance, better API design, and support for modern Kotlin features. They play nicer with coroutines and Compose, which is where we're all heading, right?

If you're still clinging to Picasso like it's the last slice of pizza at a party, it might be time to consider migrating. Embrace the new kids on the block—they've got some neat tricks up their sleeves.

But let's take a moment to tip our hats to Picasso for its years of service. Thanks for all the images, pal! 📷

🥂 Tipsy Tip

Ever been frustrated by flaky screenshot tests caused by a blinking cursor? One minute your tests pass, the next they fail—all because of that pesky cursor blinking away like a disco light at a 70's party.

Well, fret no more! Say hello to LocalCursorBlinkEnabled , a new CompositionLocal in Jetpack Compose that allows you to control whether the blinking behavior of a cursor in text input components should be enabled.

Why is this important?

Screenshot tests are an essential part of ensuring UI consistency. An ever-blinking cursor can introduce randomness in your tests, leading to false negatives and a lot of head-scratching. By disabling the cursor blink, you eliminate this source of flakiness.

Here's how you can use it:

CompositionLocalProvider(
    LocalCursorBlinkEnabled provides false
) {
    BasicTextField(
        value = text,
        onValueChange = { text = it }
    )
}

By wrapping your TextField or BasicTextField in a CompositionLocalProvider and setting LocalCursorBlinkEnabled to false , you ensure that the cursor remains steady as a rock. 🪨

But wait, there's more!

Disabling cursor blink isn't just useful for tests. Consider accessibility scenarios or custom text input components where you might want to control cursor behavior explicitly.

😆 Dev Delight

Might’ve lost on love, but clearly winning in life 😂

Might’ve lost on love, but clearly winning in life 😂

One of the perks of having non technical parents is that I’ll never receive COBOL code as inheritance

One of the perks of having non technical parents is that I’ll never receive COBOL code as inheritance…

🎥 Media Player

###JetBrains’ Quest for True Hot Reload 🔥

Folks, fasten your seatbelts! JetBrains is experimenting with a true "Hot Reload" functionality for Compose Multiplatform. If you're thinking, "Wait, don't we already have Live Edit?" - check out this list of limitations that currently exist in Live Edit

Live Edit Limitations

The long list of limitations that exist in Live Edit. Boy is this list long 😱

What's the big deal?

Live Edit in Android Studio is a step in the right direction, but let's face it—it has its limitations. It's not a pure implementation of Hot Reload, and sometimes feels like trying to fit a square peg in a round hole.

Enter JetBrains' experimental project, codenamed Firework. In a recent video, the JetBrains team showcases a prototype that delivers real-time code changes without losing the app state.

Imagine changing your Compose UI code, hitting save, and seeing the changes reflected instantly in your running app, without recomposition or losing your place. It's like magic—but better, because it's real!

Why should you care?

As developers, we strive for productivity and fast feedback loops. Waiting for builds and redeploys can break our flow, leading to frustration and decreased efficiency. With true Hot Reload, you can:

  1. Iterate rapidly on UI changes.
  2. Maintain app state, saving you from navigating back to the screen you're working on after every change.
  3. Boost productivity, making development more enjoyable.

My two cents 🪙

This development is exciting not just because of the feature itself, but also because of what it represents: the maturation of the Compose Multiplatform ecosystem. JetBrains is pushing the boundaries, providing tools that enhance our development experience across platforms.

While it's still experimental, the implications are huge. It could level the playing field with frameworks like Flutter, which has had Hot Reload as one of its flagship features.

So keep an eye on this space—2025 might just be the year Hot Reload becomes a standard part of our Compose development toolkit!

🍾 Pop Quiz: Solution

val foo = remember { foo() }
DisposableEffect(foo) {
  onDispose {
    // Is this guaranteed to be called in all cases?
    foo.dispose()
  }
}

The answer to this question is really nuanced and one that requires really in depth knowledge of the internals that might not be obvious to a lot of people that work on Jetpack Compose itself as well (as evident from this interaction).

When we look at the implementation of the DisposableEffect, we notice that it’s an implementation of the RememberObserver and the dispose function is called in the onForgotten case but not in the onAbandoned case. This means that the disposed is called if the effect was successfully “remembered” but otherwise the dispose call gets skipped. This should happen in a really limited number of cases, but if correctness is absolutely important for your use case, there’s an easy way to handle it.

You can imagine creating a helper function that handles the onAbandoned case explicitly by doing something along the lines of:

val foo = remember {
  object : RememberObserver {
    val value = foo()

    override fun onRemembered() {}
    override fun onForgotten() {
      value.dispose()
    }
    override fun onAbandoned() {
      value.dispose()
    }
  }
}.value

Full credit to Jetpack Compose core team member Adam Powell for enlightening us with his deep Compose knowledge and expertise 🧠

🦄 How you can help?

👉🏻 If you enjoyed this newsletter, I'd greatly appreciate it if you could share it with your peers and friends. Your support helps me reach more Android developers and grow our community. Writing this newsletter takes time and effort, and it truly makes my day when I see it shared within your network. Consider tweeting about it or sharing it in your team's Slack workspace. Thank you!

👉🏻 If you find this newsletter or any of my other free websites or open source contributions useful, consider supporting my work 🙏🏻

👉🏻 Get my Maker OS Notion Template that I use to run my life on Notion. If you are into productivity, you will appreciate it! Here’s a quick preview of what it looks like—

On that note, here’s hoping that your bugs are minor and your compilations are error free.

Welcome to the VIP club
To read the rest of the post, subscribe and never miss an issue!
Already a subscriber? Use the same email id to login again.