Archives
All the articles I've archived.
-
HTTP Read/Write Timeouts and OAuth 2.0 Explained
Understand the common misconception about read timeout — it is a per-chunk timer, not a total response timer — how write timeout works for uploads, and how OAuth 2.0 separates authentication from authorization to avoid sending credentials on every request.
-
Multipart Requests and Range Header — How Pause and Resume Downloads Work
Understand multipart HTTP requests for sending mixed content types in one POST, and how the Range header enables pause and resume downloads — the client tracks the last byte received and resumes from exactly that position.
-
OkHttp Connection Pooling and Retrofit with Multiple Base URLs
Understand OkHttp connection pooling — how it saves the DNS and TLS handshake overhead on repeat requests — and the three approaches for using Retrofit with multiple base URLs, with a decision guide for when to use one versus two OkHttp instances.
-
HTTP Methods Explained — HEAD, POST, PUT, and PATCH
Understand the purpose of HEAD, POST, PUT, and PATCH HTTP methods — when to use each, how HEAD avoids downloading a body to check metadata, how POST creates resources, and the difference between PUT replacing a full record and PATCH updating specific fields.
-
OkHttp vs Retrofit — How Android Networking Works Internally
Understand the difference between OkHttp and Retrofit — OkHttp is the HTTP engine that makes network calls, Retrofit is a wrapper that adds adapter pattern support, automatic parsing, and threading integration. Covers the history from HttpUrlConnection to OkHttp, and why Moshi is faster than Gson.
-
Android Starter Pattern and Adapter Click Listener Best Practice
Learn the Android starter pattern — a static factory method that hides Intent keys and enforces required parameters — and why adapters should never open activities directly, using a higher-order function as an item click listener instead.
-
Android LiveData — Observable, Lifecycle-Aware, and the Two-Variable Pattern
Understand LiveData's two core properties — observable data holder and lifecycle-aware delivery — the difference between setValue and postValue, and why ViewModel uses a private MutableLiveData with a public LiveData to enforce MVVM boundaries.
-
Lambdas, Higher-Order Functions, and Typealias in Kotlin
Understand lambdas as functions, higher-order functions that accept or return functions, how Java interface listeners map to Kotlin lambda parameters, and how typealias improves readability without adding runtime cost.
-
Android ViewModel Internals — ViewModelProvider, ActivityThread, and the Factory Pattern
Understand the full internal chain of Android's ViewModel — how ViewModelProvider, ComponentActivity, NonConfigurationInstance, ViewModelStore, and ActivityThread work together across three lifecycle scenarios, and when a ViewModelFactory is required.
-
Android ViewModel Internals — Why Data Gets Lost on Rotation and How to Fix It
Build a ViewModel from scratch to understand why Android data is lost on orientation change, how storing it in the Application class fixes one problem but introduces another, and the two rules every ViewModel must follow.
-
Debounced Search in Android with Kotlin Flow — debounce, filter, distinctUntilChanged, flatMapLatest
Build an optimized search with Kotlin Flow — understand how debounce, filter, distinctUntilChanged, and flatMapLatest each solve a specific problem, and why flatMapMerge causes silent UI bugs.
-
Parallel Network Calls and Error Handling in Kotlin Flow — zip, catch, and emitAll
Learn how zip runs two network calls in parallel in Kotlin Flow, how catch handles errors at the pipeline level and per-task level, and how emitAll provides fallback values when one call fails.
-
map vs flatMapConcat in Kotlin Flow — When Your Transformation Returns a Flow
Learn the exact difference between map and flatMapConcat in Kotlin Flow — when to use each, what their transform return types mean, and how to chain serial network calls correctly.
-
flowOn: How Kotlin Flow Controls Which Thread Your Operators Run On
Learn how flowOn acts as a thread bridge in Kotlin Flow, which operators run on which dispatcher, and the most common mistake developers make when assuming IO work runs on the IO thread.
-
How Kotlin Flow Works Internally — Upstream, Downstream, and the Operator Chain
Understand how Kotlin Flow is built internally — the Function and Collector interfaces, upstream vs downstream, the operator chain, SAM interfaces, cold Flow, and single vs multiple emissions.
-
Android BitmapPool and inBitmap: Eliminating GC-Caused UI Lag While Scrolling
Learn how BitmapPool and the inBitmap option eliminate the third image-loading problem — GC-caused UI freezes during RecyclerView scrolling — by reusing bitmap memory instead of allocating and discarding it.
-
Android Image Caching: RAM, Disk, LRU Eviction, and the Two-Level Strategy
Understand Android's two-level image cache — RAM and disk — how LRU eviction keeps it bounded, and how the memory-disk-network waterfall turns a 7-second cold load into an instant repeat load.
-
Why Images Load Slowly in RecyclerView and How Glide Fixes It with ViewTreeObserver
Learn why fast scrolling in a RecyclerView causes slow image loading, how thread queues get clogged by already-scrolled-past items, and how Glide uses ViewTreeObserver to cancel unwanted tasks at exactly the right moment.
-
Android Image Loading: OOM, Downsampling, and the Bandwidth Problem
Understand what really happens when Android loads an image — the download and decode pipeline, why large images cause OOM crashes, how downsampling fixes it, and the hidden bandwidth waste most apps accept.
-
Dagger 2 Fundamentals: Module, Component, Scope, and Qualifier Explained
A practical walkthrough of Dagger 2 core concepts — why it exists, how @Module, @Component, @Provides, @Inject, @Singleton, and @Qualifier work, and how compile-time code generation makes it faster than reflection-based DI.
-
Coroutine Dispatchers, Scopes, launch vs async, and Exception Handling in Android
Master Kotlin coroutine dispatchers (Main.immediate vs Main), lifecycle-aware scopes, when to use launch vs async vs withContext, job cancellation, and how exceptions propagate differently in each builder.
-
Kotlin Coroutine Internals: Continuation, CPS, and Why 100k Coroutines Won't Crash Your App
Understand how Kotlin suspend functions work under the hood — the Continuation interface, Continuation Passing Style, why 100k coroutines succeed where 100k threads crash, and how coroutines eliminate idle thread waste.
-
Thread-Safe Singleton in Android: Why Double-Checked Locking Exists
Learn why naive singleton implementations break under multithreading, why synchronized alone is not enough, and how double-checked locking solves the problem correctly.
-
IO vs Computation Thread Pools — Why Android Has Two and When to Use Each
Learn why Android exposes two thread pools — IO and Computation — what makes them fundamentally different, and how Dispatchers.IO and Dispatchers.Default map to each.
-
Dependency Injection vs Inversion of Control in Android: A Practical Guide
Understand the difference between Dependency Injection and Inversion of Control with a step-by-step Car, Engine, Motor example. Learn why good code means writing more lines — and why that's worth it.
-
Keep-Alive Time, Multiple Thread Pools, and Why 4 Threads Can Beat 40
Understand keep-alive time, why separating tasks into multiple thread pools improves UX, and the experiment that proves fewer threads can finish 10,000 tasks faster than more threads.
-
Android Thread Pool: How Core Size, Max Size, Queue, and Rejection Actually Work
Learn why unlimited threads crash apps, how a thread pool fixes it with four key parameters — core size, max size, keep-alive time, and queue capacity — and exactly when rejection happens.
-
How to Change FreePBX IP Address on Debian 12 - Complete Guide 2026
Step-by-step guide to safely change FreePBX IP address on Debian 12 without breaking SIP registration. Includes troubleshooting tips and firewall configuration.
-
How to Change FusionPBX IP Address Safely (Without Breaking SIP, RTP & FreeSWITCH)
Learn how to safely change the FusionPBX IP address without breaking SIP registration, RTP audio, or FreeSWITCH configurations. Step-by-step expert guide.
-
How to Remove Voicemail Menu Options in FusionPBX - Disable Options 5, 8, 9
Learn how to customize FusionPBX voicemail by removing unwanted menu options (callback, forward, save to folder). Step-by-step guide to edit FreeSWITCH XML and Lua scripts for a cleaner voicemail experience.
-
Flow vs Suspend in Room DAO - When to Use Which in Jetpack Compose
Learn the key differences between Flow and suspend in Room DAO. Understand when to use Flow for real-time updates and suspend for one-time operations in Jetpack Compose apps.
-
Install Piper TTS on Debian Linux(Offline Neural Text-to-Speech Guide)
Step-by-step guide to install and test Piper TTS on Debian Linux, including downloading an English voice model and generating speech offline.
-
Install Qt 6.8.0 Offline on Ubuntu
Complete step-by-step guide to install Qt 6.8.0 LTS offline on Ubuntu 24.04. Includes all dependencies, build configuration, and troubleshooting tips.
-
Enable TLS in FusionPBX with Let's Encrypt
Step-by-step guide to enable TLS/SSL in FusionPBX using Let's Encrypt certificates for secure SIP communication on internal and external profiles.
-
Android IPC: When to Use Content Provider vs AIDL
Learn the difference between Content Provider and AIDL for Android inter-process communication. Understand which to use based on your data type and communication pattern.
-
How Instagram Runs Smoothly: Multi-Process Architecture and C++ NDK in Android
Discover why Instagram stays smooth despite handling heavy media. Learn how Android's multi-process architecture, native C++ memory, and JNI work together to eliminate UI lag.
-
How to Configure FreeSWITCH ESL for External Access
Step-by-step guide to configure FreeSWITCH Event Socket Layer (ESL) for external access, including firewall rules, ACL setup.
-
Complete Guide to Installing Debian Linux on VirtualBox VM
Complete step-by-step guide to install Debian Linux on VirtualBox virtual machine with screenshots and post-installation configuration.
-
Why Reflection is Slower Than Direct Object Creation in Java
Discover why using reflection to create objects in Java is slower than direct instantiation. Learn with code examples, performance insights, and best practices for efficient Java development.
-
Why largeHeap Is Bad for Android Apps: Performance & Memory Explained
Learn why using the largeHeap flag in Android can cause more harm than good, and discover best practices for efficient memory management.
-
Why Android Apps Lag: Understanding Garbage Collection and Main Thread Performance
Learn how Android's garbage collector and main thread management impact app performance, why apps lag, and how to optimize our code for smooth UI experiences.
-
What Happens When an Android App Launches: Behind the Scenes of Memory Allocation
A deep dive into how Android allocates memory when an app launches, with real-world examples and a clear lifecycle diagram.
-
How to Visualize Dagger Dependency Graphs in Android with Scabbard
Learn how to integrate Scabbard into your Android project to visualize Dagger dependency graphs. Step-by-step guide for better dependency management.
-
How to Fix Android Emulator Exit Code -1073741515 (0xC0000135) on Windows
Learn how to quickly fix the Android Emulator error "Exit Code -1073741515 (0xC0000135)" on Windows by installing the Microsoft Visual C++ Redistributable.