Dispatch Issue #14


Hello Friends. This is JetpackCompose.appâs Dispatch. Whether youâre battling flaky Compose previews, optimizing your dependency graphs, or just trying to keep your caffeine intake under 400mg, weâre back with the latest, greatest, and occasionally strangest happenings in the Android ecosystem.
This is Issue # 14 so grab your favorite mug, silence those Slack notifications, and letâs dive in!
đ€ Interesting tid-bits
In-person interviews are having a renaissance
Thanks to the rise of undetectable AI-powered cheating tools (looking at you, InterviewCoder ), tech giants like Apple and Meta have pressed "Ctrl+Z" on remote-only interviews. The new trend? Back to the conference room, whiteboards, andâdare we sayâawkwardly sharing a marker. The reason: LLM-based cheating is rampant, and some platforms are raking in serious cash (InterviewCoderâs founder claims heâs making $200,000+/month from his tool with 96% profits đ€Ż) from those looking to game the system.
Bufferâs radical transparency
If you want to know what your favorite Buffer engineer earns, you donât need to guess (or stalk LinkedIn). I recently learnt that Buffer publishes all employee (yes, every single employee!!) salaries in a public spreadsheet . Their goal? Demystify compensation and push the whole industry forward. Spoiler: Openly sharing salaries doesnât seem to have caused the world to implode. Maybe honesty is the best policy. Check it out.
Googleâs Big Bet: Firebase Studio and Agentic Developer Workflows
Missed Google Cloud Next? Hereâs the scoop: Google just launched Firebase Studio , a cloud-based, Gemini-powered environment that lets you build full-stack AI appsâright from your browser. This isnât just another âprompt-to-appâ toy; itâs a tightly integrated, agentic workflow for serious developers.
I have a lot of thoughts on this but want to reserve that for a future issue of newsletter because I want to do a deep dive and talk about the overall ecosystem. This does ship with 60+ templates that one can choose from and the Android ones are specifically for cross-platform frameworks such as React Native and Flutter. Stay tuned for a longer and more detailed deep-dive soon!
đ Dev Delight
đ”đ»ââïž Insider Insight
âCrime, but with Honorâ: Using Internal APIs Across Modules
I recently stumbled on this blogpost from engineer extraordinaire Jesse Wilson and I was blown away that this was even possible. So letâs talk about a Kotlin hack so spicy it should come with a warning label. Ever needed to access an internal
API from outside its module? No public API, no problem! Hereâs the (occasionally justifiable) âcrimeâ:
@file:Suppress(
"CANNOT_OVERRIDE_INVISIBLE_MEMBER",
"INVISIBLE_MEMBER",
"INVISIBLE_REFERENCE",
)
// ...now use that internal API like you own the place...
Why would anyone do this? Sometimes, youâre building internal tools or advanced tests and really donât want to expose half-baked APIs to the universe. This trick lets you keep your production codeâs visibility tight while still poking at those juicy internals from your test modules or internal dev tools.
When is this actually âhonorableâ?
- Internal toolchains: You own both modules, and you want to keep your prod API clean without making everything public just for a test.
- Rapid prototyping: Occasionally, thereâs no public API yet (and youâre the one who might write it later).
- Legacy hacks: Sometimes, itâs the least-worst way to keep legacy code under control.
Dangers & Dragon-Caves
- Upgrade roulette: Non-public APIs are much more likely to change, break, or vanish without warning.
- Test/prod divergence: Using different versions of internal APIs in tests vs. runtime? Prepare for some âfunâ debugging adventures.
- Kotlin evolution: As the language and tooling evolve, even these suppression hacks might break, or at minimum, emit enough warnings to fill a logcat buffer.
Pro Tip
If you must do this, do it judiciouslyâand document the hack in a way that future-you (or your team) wonât curse your name. Sometimes, the âhonorable crimeâ is just the pragmatic move.
đ€ż Deep-dive to avoid jitter when scaling text
Ever noticed that scaling text in Jetpack Compose sometimes looks like itâs been downing double espressos? That jittery, wobbly effect isnât just your eyesâitâs a sideâeffect of how Android rasterizes and lays out text, especially when you animate its size.
Halil Ozercan (a.k.a. the wizard of Text
on the Compose team) just dropped a fantastic deepâdive on why text gets jittery when scaled andâmore importantlyâ what you can do about it . Before we unpack his tips, hereâs a 60âsecond cheat sheet so you donât have to Google every term that youâve probably familiar with (I wasnât either):
Concept | âWait, what is that?â |
---|---|
Concept | âWait, what is that?â |
Font hinting | Pixelâlevel nudges baked into a font so characters stay crisp at small sizes. Great for readability, terrible for smooth scaling because it snaps glyphs to integer pixels. |
Subâpixel positioning | Lets glyphs land between physical pixels, giving smoother horizontal motion (especially on LCD screens with RGB strips). |
LINEAR_TEXT_FLAG | Tells Android to disable hinting for more âanalogâ scaling. Translation: fewer jumps, more smoothness. |
SUBPIXEL_TEXT_FLAG | Unlocks subâpixel bliss. Combine with linear text for silky animations. |
đš The Problem
- Scaling via
graphicsLayer
: The âobviousâ approachâwrap text ingraphicsLayer { scaleX/scaleY }
âoften yields that jitter, especially at fractional scales or lower DPI. - Hinting vs. subâpixel tugâofâwar: Androidâs renderer mixes hinting, linearity flags, and subâpixel logic. Hinting wants integer pixels; subâpixel wants freedom. In simpler terms, when you animate scale text, the tugâofâwar makes the glyphs dance.
đ§ The Levers You Can Pull
LINEAR_TEXT_FLAG
â Disables hinting â smoother continuous scaling.SUBPIXEL_TEXT_FLAG
â Lets glyphs sit between pixels â kills horizontal jitter.- Drop hinting (when animating) â Crispness isnât your goal midâanimation; smoothness is.
âš The Modern Solution: CompositingStrategy.Offscreen
modifier = Modifier.graphicsLayer {
scaleX = scale
scaleY = scale
compositingStrategy = CompositingStrategy.Offscreen
}
- What it does: Renders the text once to an offâscreen buffer, then treats that buffer like an image for scaling.
- Sweet spot: 0.8Ă â 1.2Ă (perfect for Wear OS pickers, pillâbutton animations, etc.).
- Tradeâoff: Go huge (4Ă) and your onceâsharp text turns into a â90s JPEG.
đ Bonus Candy: TextMotion
Text(
text = "Hello",
modifier = Modifier
.graphicsLayer {
scaleX = scale
scaleY = scale
transformOrigin = TransformOrigin.Center
}
.align(Alignment.Center),
// Text does not take TextMotion as a parameter.
// Provide it via style argument but copy from theme
style = LocalTextStyle.current.copy(
textMotion = TextMotion.Animated
)
)
TextMotion.Static
â¶ use for normal, nonâmoving text (keeps hinting).TextMotion.Animated
â¶ pick this when you animate size/position/alpha.
đ TL;DR for Reliable Text Animations
- Tiny scale animations? Slap on
CompositingStrategy.Offscreen
and call it a day. - Static text? Keep hinting ONâthatâs what itâs for.
- Animated text? Disable hinting (
LINEAR_TEXT_FLAG
) + enable subâpixel (SUBPIXEL_TEXT_FLAG
) or just useTextMotion.Animated
. - Donât overâscale unless you want that funâhouseâmirror vibe.
For the full, glorious rabbit hole, check out Halilâs original post .
đŠ 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.
