Chapter 9: Networking and APIs

Networking and APIs! This is a massive milestone — your app is about to stop being offline-only and start talking to the real world. Fetching data from servers (like weather, news, user profiles, or even memes) is what makes most modern Android apps useful.

In January 2026, for Android + Kotlin apps:

  • Retrofit (latest stable: 3.0.0 from May 2025, fully Kotlin-rewritten) is still the most popular choice (~70-75% of Android devs per recent surveys). It’s battle-tested, has huge ecosystem (converters for Moshi/Gson/Kotlinx Serialization, interceptors, etc.), and integrates beautifully with Jetpack Compose.
  • Ktor Client (latest: 3.4.0 from January 23, 2026) is gaining fast traction, especially in Kotlin-first / Kotlin Multiplatform (KMP) projects. It’s fully coroutine-native, lightweight, more flexible for custom HTTP logic, and great if you’re planning iOS/desktop sharing later. But it has a smaller Android-specific community compared to Retrofit.

Recommendation for you right now (as a learner building Android apps):

  • Use Retrofit + Kotlinx Serialization (or Moshi) for this chapter and most projects — it’s easier to learn, has better docs/tutorials, and you’ll see it in 90% of job codebases.
  • Switch to Ktor later if you go multiplatform or want more control.

We’ll use Retrofit here, but I’ll mention Ktor equivalents briefly.

Key ingredients:

  • HTTP client (Retrofit)
  • JSON parsing (Kotlinx Serialization – modern, Kotlin-idiomatic)
  • Coroutines (for async, non-blocking network calls)
  • Display in Compose

1. Retrofit Basics (Type-Safe HTTP Client)

Retrofit turns your REST API into a clean Kotlin interface.

Add dependencies (app/build.gradle.kts – use latest stable):

Kotlin

2. Define API Interface

Use annotations – super clean!

Example: We’ll fetch posts from JSONPlaceholder (free fake REST API – perfect for tutorials, no key needed).

Kotlin
  • @GET(“posts”) → Endpoint relative to base URL.
  • suspend → Lets us call it inside coroutine scope without blocking.

3. Create Retrofit Instance

Usually in a singleton/object (or via Hilt/Dagger later).

Kotlin
  • ignoreUnknownKeys → Safe if API adds extra fields.
  • Lazy → Created only when first used.

4. Coroutines for Async (No More Callback Hell)

Network calls must be off main thread. Use viewModelScope + suspend.

In ViewModel:

Kotlin
  • viewModelScope.launch → Coroutine on IO thread by default (safe for network).
  • Try-catch → Handle errors (no internet, 404, etc.).
  • State updates → Trigger Compose recomposition.

5. Display in Compose (LazyColumn + Loading/Error States)

Kotlin

6. Hands-on: Fetch Real Data from Public API

Project: Posts Feed App

  1. Use the code above.
  2. Add to MainActivity setContent:
Kotlin
  1. Run → See list of 100 fake posts load!
    • Title + body in cards.
    • Loading spinner first.
    • Retry if you turn off internet.

Bonus Challenges:

  • Add pull-to-refresh (use SwipeRefresh from accompanist or material3).
  • Show user name (fetch /users/{userId} – make another suspend fun).
  • Use Ktor instead (for comparison):

Ktor version (add implementation(“io.ktor:ktor-client-android:3.4.0”) + ktor-client-content-negotiation + ktor-serialization-kotlinx-json):

Kotlin

But stick with Retrofit for now – it’s what most jobs expect.

Common Pitfalls & Tips (2026 edition):

  • Add <uses-permission android:name=”android.permission.INTERNET” /> in Manifest!
  • Handle no-internet: Use ConnectivityManager or just catch IOException.
  • Add logging: Add HttpLoggingInterceptor (OkHttp) for debug.
  • Caching: Add Room + offline support later.
  • Rate limits: JSONPlaceholder is unlimited, but real APIs need API keys (e.g., OpenWeather).

You’ve connected your app to the internet! Questions? Want to fetch real weather API? Add images from Unsplash? Handle auth tokens? Pagination with Paging 3? Tell me — next chapter: Architecture patterns (MVVM, Hilt). You’re building full-featured apps now — incredible progress! 🚀🌐

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *