All Products
Search
Document Center

HTTPDNS:Best Practices for using HTTPDNS with OkHttp on Android

Last Updated:Apr 17, 2025

This document describes how to integrate HTTPDNS with OkHttp on Android clients.

1. Background

If you use OkHttp as the network framework on Android, you can elegantly integrate HTTPDNS services by calling the custom DNS service interface provided by OkHttp.

OkHttp is an open source lightweight Android framework for processing network requests. It is developed by Square as an alternative to HttpURLConnection and Apache HttpClient. Since its release, OkHttp has gained popularity among Android developers as it has matured.

OkHttp uses the system DNS service InetAddress for domain name resolution by default. It also provides the Dns API for developers to customize DNS resolution based on business requirements.

Note

This practice also applies to Retrofit+OkHttp. You can pass the configured OkHttpClient as a parameter to Retrofit.Builder::client(OkHttpClient).

2. Custom DNS interface

OkHttp provides the Dns API for developers to customize DNS resolution:

class OkHttpDns constructor(context: Context): Dns {
    private var mContext: Context

    init {
        mContext = context
    }
    @Throws(UnknownHostException::class)
    override fun lookup(host: String): List<InetAddress> {
        val httpdnsResult: HTTPDNSResult = HttpDns.getService(accountID)
            .getHttpDnsResultForHostSync(host, RequestIpType.both)
        val inetAddresses: MutableList<InetAddress> = ArrayList()
        var address: InetAddress
        try {
            if (httpdnsResult.ips != null) {
                // Process IPv4 addresses
                for (ipv4 in httpdnsResult.ips) {
                    address = InetAddress.getByName(ipv4)
                    inetAddresses.add(address)
                }
            }
            if (httpdnsResult.ipv6s != null) {
                // Process IPv6 addresses
                for (ipv6 in httpdnsResult.ipv6s) {
                    address = InetAddress.getByName(ipv6)
                    inetAddresses.add(address)
                }
            }
        } catch (e: UnknownHostException) {
        }
        return if (!inetAddresses.isEmpty()) {
            inetAddresses
        } else Dns.SYSTEM.lookup(host)
    }
}
public class OkHttpDns implements Dns {
    private Context mContext;
    public OkHttpDns(Context context) {
        mContext = context;
    }
    @Override
    public List<InetAddress> lookup(String host) throws UnknownHostException {
        HTTPDNSResult httpdnsResult = HttpDns.getService(accountID).getHttpDnsResultForHostSync(host, RequestIpType.both);
        List<InetAddress> inetAddresses = new ArrayList<>();
        InetAddress address;
        try {
            if (httpdnsResult.getIps() != null) {
                // Process IPv4 addresses
                for (String ipv4 : httpdnsResult.getIps()) {
                    address = InetAddress.getByName(ipv4);
                    inetAddresses.add(address);
                }
            }

            if (httpdnsResult.getIpv6s() != null) {
                // Process IPv6 addresses
                for (String ipv6 : httpdnsResult.getIpv6s()) {
                    address = InetAddress.getByName(ipv6);
                    inetAddresses.add(address);
                }
            }
        } catch (UnknownHostException e) {

        }

        if (!inetAddresses.isEmpty()) {
            return inetAddresses;
        }

        return okhttp3.Dns.SYSTEM.lookup(host);
    }
}

Because okhttp has an internal retry mechanism that might select different IP addresses to establish connections during retries, the lookup() method in the Dns interface can return a List<InetAddress> containing multiple IP addresses. This effectively prevents request failures that might occur when a single IP address is returned but is unavailable.

3. Configure OkHttpClient

Create an OkHttpClient object and pass in the OkHttpDns object instead of the default DNS service:

private fun initOkHttp(context: Context) {
    val client = OkHttpClient.Builder() 
        // Configure other initialization settings of OkHttp as required
        .dns(OkHttpDns(context))
        .build()
}
private void initOkHttp(Context context) {
    OkHttpClient client = new OkHttpClient.Builder()
    // Configure other initialization settings of OkHttp as required
    .dns(new OkHttpDns(context))
    .build();
}

The preceding code provides an example of how to use HTTPDNS and OkHttp to connect an Android app to an IP address.

4. Summary

The combination of OkHttp and HTTPDNS provides the following benefits:

  • You only need to implement an API for DNS service customization to access HTTPDNS.

  • This solution applies to scenarios where HTTPS, Server Name Indication (SNI), and cookies are configured. This solution eliminates the need to perform certificate verification and domain name check.