Posts

Part 2: Designing the Core Sync Engine

Image
 How to design idempotent, resilient background synchronization using WorkManager and the Command Pattern. In  Part 1 , we established the “Offline-First” mindset: the UI observes the local database. But how do we ensure user actions — likes, comments, or edits — actually reach the server without getting lost in “Lie-Fi”? Welcome to the heart of the machine:  The Sync Engine. 1. The Action Outbox: Preserving Intent In a production-grade  mobile sync engine design , you don’t just “call an API.” You encapsulate intent. The  Outbox Pattern  ensures that an action survives process death and device reboots. Kotlin Implementation: The Action Entity @Entity (tableName = "pending_actions" ) data class PendingAction ( @PrimaryKey (autoGenerate = true) val id : Long = 0 , val type : String, // e.g., "ADD_COMMENT", "UPDATE_PROFILE" val payload : String, // Versioned JSON or Protobuf val status : ActionStatus = ActionStatus.PENDING, val retryCount...

Part 1: The "Lie-Fi" Problem & The Offline-First Mindset

Image
 How Senior Engineers use SSOT, Room, and Flow to build resilient, production-grade apps that never feel broken. TL;DR The Problem:  “Online-first” apps break in “Lie-Fi” (zombie connections). The Fix:  Move from Request-Response to  Single Source of Truth (SSOT) . The Flow:  UI observes Room → Network updates Room → UI reacts. Priority:  Choose  Availability  (AP) over strict Consistency. 1. The “Online-First” Fallacy In an online-first model, the  UI becomes tightly coupled to the variability of network conditions . This creates a fragile experience where usability is tethered to the health of a remote socket. The “Zombie” Connection (Lie-Fi):  The TCP socket hasn’t timed out, but no data is moving. The app waits for an  onResponse  that may take tens of seconds (or never) to resolve. To the user, the app isn't "waiting"—it's  broken . Real-World Failure Scenario: User “Likes” a photo → Network stalls → Heart doesn’t tur...

Beyond the Surface: Mastering Jetpack Compose Preview Internals & Scalable Patterns

Image
 Why your inability to preview a Composable is actually a signal of technical debt. Most Android developers treat  @Preview  as a visual convenience. But for senior engineers, Preview is a  UI contract . If a Composable cannot be previewed without heavy workarounds, your architecture is likely trying to tell you something. 1. The Internal Mechanics: How It Actually Renders When you hit the “split” view in Android Studio, you aren’t running your app. You are engaging a coordinated dance between the Kotlin compiler, the Compose compiler, and the IDE. The Mental Model The rendering pipeline follows a strict sequence to simulate your UI without a full device environment: @Preview Discovery:  The IDE scans Kotlin metadata and Compose compiler tables. Adapter Layer:  A synthetic wrapper is generated to prepare parameters and environment. Layoutlib Sandbox:  A sandboxed subset of the Android framework provides a mock  Context  and resources. Bitmap ...