Dispatch Issue #14

In today's issue, we talk about 🧐 cheating during interviews, 💾 fully transparent salaries, đŸȘ„ Google's big agentic bet, đŸ•”đŸ»â€â™‚ïž committing a Kotlin crime and đŸ«š jittery text animations
Vinay Gaba Profile Image
Vinay Gaba on April 19, 2025
Hero Image

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.

Meta & Apple call candidates for inperson interviews

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.

Buffer transparently shares the salaries of all their employees on a public spreadsheet

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!

Firebase Studio Demo

😆 Dev Delight

JetpackCompose.app
JetpackCompose.app
@JetpkComposeApp
Twitter logo
Watching LLMs rewrite my classes for absolutely no reason 😑
Hero Image
Josh Cohenzadeh
Josh Cohenzadeh
@jshchnz
Twitter logo
MoBiLe iS dYInG
Hero Image

đŸ•”đŸ»â€â™‚ïž 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”?

  1. Internal toolchains: You own both modules, and you want to keep your prod API clean without making everything public just for a test.
  2. Rapid prototyping: Occasionally, there’s no public API yet (and you’re the one who might write it later).
  3. Legacy hacks: Sometimes, it’s the least-worst way to keep legacy code under control.

Dangers & Dragon-Caves

  1. Upgrade roulette: Non-public APIs are much more likely to change, break, or vanish without warning.
  2. Test/prod divergence: Using different versions of internal APIs in tests vs. runtime? Prepare for some “fun” debugging adventures.
  3. 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 hintingPixel‑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 positioningLets glyphs land between physical pixels, giving smoother horizontal motion (especially on LCD screens with RGB strips).
LINEAR_TEXT_FLAGTells Android to disable hinting for more “analog” scaling. Translation: fewer jumps, more smoothness.
SUBPIXEL_TEXT_FLAGUnlocks sub‑pixel bliss. Combine with linear text for silky animations.

🚹 The Problem

  1. Scaling via graphicsLayer : The “obvious” approach—wrap text in graphicsLayer { scaleX/scaleY } —often yields that jitter, especially at fractional scales or lower DPI.
  2. 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

  1. LINEAR_TEXT_FLAG – Disables hinting → smoother continuous scaling.
  2. SUBPIXEL_TEXT_FLAG – Lets glyphs sit between pixels → kills horizontal jitter.
  3. 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
}
  1. What it does: Renders the text once to an off‑screen buffer, then treats that buffer like an image for scaling.
  2. Sweet spot: 0.8× – 1.2× (perfect for Wear OS pickers, pill‑button animations, etc.).
  3. 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
     )
)
  1. TextMotion.Static ⟶ use for normal, non‑moving text (keeps hinting).
  2. TextMotion.Animated ⟶ pick this when you animate size/position/alpha.

📝 TL;DR for Reliable Text Animations

  1. Tiny scale animations? Slap on CompositingStrategy.Offscreen and call it a day.
  2. Static text? Keep hinting ON—that’s what it’s for.
  3. Animated text? Disable hinting ( LINEAR_TEXT_FLAG ) + enable sub‑pixel ( SUBPIXEL_TEXT_FLAG ) or just use TextMotion.Animated .
  4. 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.

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