Android Using Okhttp And Interceptors Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    7 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of Android Using OkHttp and Interceptors

Android Usage of OkHttp and Interceptors Explained in Detail

OkHttp is a high-performance HTTP client for Android that is widely used due to its efficiency and comprehensive feature set. Developed by Square, OkHttp simplifies network operations, handles automatic reconnection and caching, and supports modern networking concepts like protocols (HTTP/2 and SPDY) and connection pooling.

Installation

To use OkHttp in your Android project, add the following dependencies to your build.gradle file:

dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.1'
    // For logging interceptor
    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
}

Creating Basic OkHttpClient

The foundation of using OkHttp in Android applications involves creating an instance of OkHttpClient. This object can be configured with different options for request handling. Here’s how you can create a basic OkHttpClient:

OkHttpClient client = new OkHttpClient();

Making Synchronous Requests

For synchronous requests, you need to execute the request on a background thread as blocking operations are not permitted on the main UI thread.

Request request = new Request.Builder()
    .url("https://api.github.com/users/square/repos")
    .build();

try (Response response = client.newCall(request).execute()) {
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    // Use the response body...
    System.out.println(response.body().string());
}
catch (IOException e) {
    e.printStackTrace();
}

Making Asynchronous Requests

Asynchronous requests do not block the thread; instead, they return immediately, and a callback method is executed once the response is received.

Request request = new Request.Builder()
    .url("https://api.github.com/users/square/repos")
    .build();

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        e.printStackTrace();
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            final String myResponse = response.body().string();
            MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // handle result on UI thread 
                }
            });
        }
    }
});

Interceptors

Interceptors are a powerful mechanism to modify or observe request and response data before they reach the application. OkHttp supports three types of interceptors:

  • Application Interceptors: Operate inside the OkHttp chain. They have no access to the underlying connection.
  • Network Interceptors: Operate outside of the application layer, which allows them to see every request and response. They can be useful if you want to monitor the network activity.
  • Custom Interceptors: You can also create custom interceptors to perform operations like adding headers, altering the request body, handling redirects, or managing authorization.

Adding Interceptors

Application interceptors can be added via the addInterceptor method. Network interceptors are added using the addNetworkInterceptor method. Below is an example of adding two interceptors – a logging interceptor and a custom header interceptor:

OkHttpClient.Builder builder = new OkHttpClient.Builder();
// Adding Logging Interceptor
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(logging);

// Adding Custom Header Interceptor
builder.addInterceptor(new Interceptor() {
    @NonNull
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request originalRequest = chain.request();

        Request requestWithHeader = originalRequest.newBuilder()
            .header("Authorization", "Bearer YOUR_ACCESS_TOKEN_HERE")
            .build();

        return chain.proceed(requestWithHeader);
    }
});

OkHttpClient client = builder.build();

Important Info

  • Automatic Connection Pooling: OkHttpClient automatically manages a connection pool to reduce latency for repeated requests to the same host.
  • SPDY support: OkHttp enables multiplexed requests to the server over fewer connections; it uses this to send all requests in parallel over the same socket.
  • GZIP Compression: It compresses responses automatically for you and reduces payload sizes.
  • Caching: Caches the responses to minimize network usage. It is configurable and supports Conditional GETs and full response caching.
  • Error Handling: Supports retry and recovery from common connection problems.
  • Timeouts: You can set timeouts for connect, read, and write. This avoids stalled operations indefinitely.
  • Custom Network Stack: Allows developers to replace the default transport layer with their own, for debugging or testing purposes.
  • Logging Interceptor: This interceptor is widely used for logging the request and response data.
  • Thread Safety: OkHttpClient instances are intended to be used across multiple threads.

Use Cases

  1. Caching: Utilizing built-in response caching mechanisms to improve loading times and minimize network usage.
  2. Retry Mechanisms: Implementing custom or built-in retry mechanisms for failed network requests.
  3. Request Authentication: Automatically adding authentication headers to all outgoing requests.
  4. Protocol Negotiation: Efficiently negotiating between HTTP/2, HTTP/1.1, and SPDY protocols.
  5. Monitoring Traffic: Using logging interceptors to monitor HTTP traffic during development and debugging.
  6. Performance Tuning: Adjusting timeouts and connection pool size for optimal performance based on application needs.

Conclusion

OkHttp and its interceptors are essential tools for effective network management in Android applications. They provide rich functionalities to build robust, efficient, and maintainable networking solutions. Understanding how to configure and use them can significantly enhance your app's network capabilities, making your app faster, more reliable, and easier to debug.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement Android Using OkHttp and Interceptors

Step-by-Step Guide to Using OkHttp and Interceptors in Android

Prerequisites:

  • Basic familiarity with Android development.
  • Android Studio installed on your machine.
  • A basic knowledge of Java/Kotlin programming.

Step 1: Set Up Your Android Project

  1. Open Android Studio.
  2. Create a new project.
  3. Choose an "Empty Activity" template.
  4. Configure your project (Name, Package name, etc.).

Step 2: Add OkHttp Dependency

Open build.gradle (Module: app) and add OkHttp dependency inside dependencies block:

dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.3' // As of this writing, 4.9.3 is the latest version
}

Sync your project with Gradle files.

Step 3: Basic Usage of OkHttp

Create a simple network call using OkHttp. We will use a synchronous call just for demonstration purposes.

Create a new class ApiService.java:

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class ApiService {
    private OkHttpClient client;

    public ApiService() {
        client = new OkHttpClient();
    }

    public String makeRequest(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .build();

        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }
}

In your MainActivity.java, use this service to fetch some data:

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = findViewById(R.id.textView);

        new Thread(() -> {
            ApiService apiService = new ApiService();
            try {
                String responseData = apiService.makeRequest("https://jsonplaceholder.typicode.com/posts/1");
                runOnUiThread(() -> textView.setText(responseData));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

Ensure you have a TextView with id textView in your activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="18sp"/>
</RelativeLayout>

Step 4: Implementing Interceptors

Interceptors allow you to intercept requests and responses. You can use them to add headers, log data, etc. We'll implement a simple logging interceptor.

Create a new class LoggingInterceptor.java:

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class LoggingInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        long startTime = System.nanoTime();
        System.out.println("\nSending request " + request.url() + " on " + chain.connection() + "\n" +
                "Request: " + request.headers());

        Response response = chain.proceed(request);

        long endTime = System.nanoTime();
        System.out.println("\nReceived response for " + response.request().url() + "\n" +
                "Took " + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "ms\n" +
                "Response: " + response.headers());

        return response;
    }
}

Now, modify your ApiService to use this interceptor:

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class ApiService {
    private OkHttpClient client;

    public ApiService() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.addInterceptor(new LoggingInterceptor());
        client = builder.build();
    }

    public String makeRequest(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .build();

        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }
}

By running the app, you should see the request and response details printed in the logcat.

Summary

In this guide, we learned how to make a simple network call using OkHttp in Android and how to use Interceptors to log requests and responses. This can be extended to add headers, modify the request body, or perform conditional requests.

Top 10 Interview Questions & Answers on Android Using OkHttp and Interceptors

1. What is OkHttp, and why should developers use it in their Android applications?

Answer: OkHttp is a powerful HTTP client library for Android and Java applications that simplifies making network calls. It supports HTTP/2 to allow multiplexing requests on a single socket, efficient connection pooling, which can significantly reduce latency, and handles redirects and retries automatically. Developers choose OkHttp for its robustness, performance, and ease of use compared to other networking libraries like Volley or HttpClient.

2. How do you set up OkHttp in an Android project?

Answer: To add OkHttp to your Android project, include the following dependency in your build.gradle file:

dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.4' // Check for the latest version
}

Then, sync your project with Gradle. Optionally, if you need additional features like logging or Gson serialization, add those dependencies as well.

3. What are interceptors in OkHttp, and how do they differ from traditional event listeners or callbacks?

Answer: Interceptors are a powerful feature in OkHttp that allow you to intercept and modify requests and responses before they reach the server or client code. Unlike traditional event listeners or callbacks, which react to completed events, interceptors can intervene at specific points during the request/response lifecycle (e.g., logging, authentication headers). This makes them very versatile for adding cross-cutting concerns like monitoring or security.

4. How do you create a custom interceptor in OkHttp?

Answer: Creating a custom interceptor involves implementing the Interceptor interface from the OkHttp library. The intercept method provides access to both the request and the response through a Chain object. Here’s a simple example of a logging interceptor:

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.logging.Logger;

public class LoggingInterceptor implements Interceptor {

    private final Logger logger = Logger.getLogger(LoggingInterceptor.class.getName());

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
        logger.info(String.format("Sending request %s on %s%n%s",
                request.url(), chain.connection(), request.headers()));

        Response response = chain.proceed(request);

        long t2 = System.nanoTime();
        logger.info(String.format("Received response for %s in %.1fms%n%s",
                response.request().url(), (t2 - t1) / 1e6d, response.headers()));

        return response;
    }
}

Add this interceptor to your OkHttpClient instance:

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new LoggingInterceptor())
    .build();

5. Can interceptors be used to modify request headers dynamically?

Answer: Absolutely! Interceptors provide a way to modify request headers (or even request bodies) before sending them to the server. Here’s an example of an interceptor that adds an "Authorization" header:

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class AuthenticationInterceptor implements Interceptor {
    private String authToken;

    public AuthenticationInterceptor(String token) {
        this.authToken = token;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request newRequest = originalRequest.newBuilder()
            .header("Authorization", "Bearer " + authToken)
            .build();
        return chain.proceed(newRequest);
    }
}

Use it by adding the interceptor to your OkHttpClient:

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new AuthenticationInterceptor("your_token_here"))
    .build();

6. What are the benefits of using application interceptors versus network interceptors in OkHttp?

Answer:

  • Application Interceptors: Run inside an application after the call adapter and only run once per user-facing call. They can change the Request body and headers, observe the outgoing Request before it’s compressed, and observe the incoming Response after it has been decompressed. Use these when you want to add or modify data globally for all requests.
  • Network Interceptors: Run inside the OkHttp transport layer. They can inspect and modify the Request and Response. Network interceptors see every outgoing request and every incoming response, including redirects and retries. They see transparently-compressed data and aren't invoked for cached responses. Use these for more specific actions, such as caching logic tailored to your API requirements.

7. How can you handle retries in OkHttp using interceptors?

Answer: You can manage retries in OkHttp by creating a custom network interceptor that checks the response status code and repeats the request if necessary. Here’s an example of a retrying network interceptor based on a specific HTTP status code:

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class RetryInterceptor implements Interceptor {
    private final int maxRetries;
    private int retryCount = 0;

    public RetryInterceptor(int maxRetries) {
        this.maxRetries = maxRetries;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = null;
        boolean responseOK;

        while (retryCount < maxRetries) {
            try {
                response = chain.proceed(request);
                responseOK = response.isSuccessful();
            } catch (IOException e) {
                retryCount++;
                continue;
            }

            if (responseOK) {
                break;
            } else {
                switch (response.code()) {
                    case 408: // Timeout
                    case 500: // Internal Server Error
                    case 502: // Bad Gateway
                    case 503: // Service Unavailable
                    case 504: // Gateway Timeout
                        retryCount++;
                        // Optionally log retries or perform other actions here
                        continue;
                    default:
                        break;
                }
                throw new IOException("Request failed: " + response.body().string());
            }
        }

        return response;
    }
}

Add it to your OkHttpClient:

OkHttpClient client = new OkHttpClient.Builder()
    .addNetworkInterceptor(new RetryInterceptor(3))
    .build();

8. Can OkHttp interceptors be used to serialize and deserialize JSON data?

Answer: While OkHttp itself does not natively handle JSON serialization or deserialization, interceptors can be combined with libraries like Gson or Moshi to parse and construct JSON. However, it’s common practice to delegate these concerns to higher-level constructs, like Retrofit converters, rather than doing it in interceptors. This keeps your network layer clean and focused on handling HTTP requests and responses.

9. How do you debug or inspect OkHttp requests and responses?

Answer: One of the best ways to debug and inspect OkHttp requests and responses is by using the HttpLoggingInterceptor. This logs all traffic passing through the OkHttpClient. First, add the logging dependency in your build.gradle:

implementation 'com.squareup.okhttp3:logging-interceptor:4.9.4'

Then, configure and attach the logging interceptor:

import okhttp3.HttpLoggingInterceptor;
import okhttp3.OkHttpClient;

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
    @Override
    public void log(String message) {
        // Log the message using your preferred logging framework, e.g., Log.i()
        Log.i("OkHttp", message);
    }
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); // Can also be BASIC, HEADERS, NONE

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(loggingInterceptor)
    .build();

Setting the level to BODY logs detailed information, including request and response headers and bodies.

10. What are some common mistakes to avoid when using OkHttp and interceptors?

Answer:

  • Improper Thread Management: Ensure that any heavy operations within an interceptor, especially those blocking, are done off the main thread to avoid ANR issues.
  • Infinite Retries: Carefully implement logic for retries to prevent infinite loops. Always have a maximum retry count or check specific conditions to stop retrying.
  • Leaking Sensitive Data: Avoid adding sensitive data like tokens directly in string literals. Use safer methods to handle secrets.
  • Ignoring Response Codes Properly: Make sure your interceptor correctly handles different response codes instead of blindly retrying or modifying headers.
  • Large Response Bodies: Be cautious when manipulating large response bodies; doing so in an interceptor might lead to memory issues.
  • Overusing Interceptors: While interceptors are powerful, overusing them can clutter the codebase and affect performance.

Summary:

Using OkHttp along with interceptors enhances the flexibility and robustness of your Android application's networking layer. Whether you’re adding authentication, logging, or custom retry logic, interceptors provide a clean, maintainable way to customize your HTTP requests and responses.

You May Like This Related .NET Topic

Login to post a comment.