Best practice for using the HTTPDNS Android SDK with OkHttp on Android

更新时间:
复制 MD 格式

Integrate the HTTPDNS Android SDK into the OkHttp framework on Android by implementing the OkHttp DNS interface.

Overview

OkHttp is a popular, lightweight, open source network framework for Android developed by Square as an alternative to HttpURLConnection and Apache HttpClient. Compared with general solutions, using OkHttp with the HTTPDNS Android SDK provides two main advantages:

  • Simple implementation. Access the HTTPDNS resolution service by implementing the DNS interface.

  • Widely applicable. No additional configurations are required for HTTPS.

Use cases

By default, OkHttp uses the system DNS service InetAddress for domain name resolution, but it also exposes a DNS interface. You can implement this interface to use the HTTPDNS Android SDK for network access without extra processing for HTTPS or HTTPS with Server Name Indication (SNI) scenarios. The integration is minimally intrusive.

Important

Implementing the DNS interface routes all network requests from the current OkHttpClient instance through HTTPDNS. If only some of your domain names require HTTPDNS resolution, filter them before calling the resolution interface of the HTTPDNS Android SDK.

Integration guide

1. Customize the Dns API

OkHttp exposes a DNS interface that you can implement to customize the DNS service. For complete sample code, see the Demo project source code.

  1. Create a new class in the project directory to implement the Dns API.

  2. Override the lookup method in the custom DNS according to the API provided in the HTTPDNS Android SDK to perform domain name resolution operations.

  public class OkHttpDns implements Dns {

    private static OkHttpDns instance;
    private static Object lock = new Object();
    private DNSResolver mDNSResolver = DNSResolver.getInstance();

    private OkHttpDns() {
    }

    public static OkHttpDns getInstance() {
        if (null == instance) {
            synchronized (lock) {
                if (instance == null) {
                    instance = new OkHttpDns();
                }
            }
        }
        return instance;
    }

    @Override
    public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
        // Call the API provided by the HTTPDNS Android SDK to resolve the domain name.
        String[] IPArray = mDNSResolver.getIpv4ByHostFromCache(hostname,true);
        if (IPArray == null || IPArray.length == 0){
            IPArray = mDNSResolver.getIPsV4ByHost(hostname);
        }
        if (IPArray != null && IPArray.length > 0) {
            List<InetAddress> inetAddresses = new ArrayList<>();
            InetAddress address;
            for (String ip : IPArray) {
                Log.d(TAG, "mDnsCache IP: " +hostname+ ip);
                address = InetAddress.getByName(ip);
                inetAddresses.add(address);
            }
            if (!inetAddresses.isEmpty()) {
                return inetAddresses;
            }
        }
        // If null is returned, the system DNS service resolves the domain name.
        return okhttp3.Dns.SYSTEM.lookup(hostname);
    }
}

2. Create an OkHttpClient

public void okhttpDnsRequest(String url, final Handler mHandler) {
        OkHttpClient client = new OkHttpClient.Builder()
                .dns(OkHttpDns.getInstance())
                .build();

        Request request = new Request.Builder()
                .url(url)
                .build();

        Response response = null;
        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()) {
                    throw new IOException("Unexpected code " + response);
                }

                DataInputStream dis = new DataInputStream(response.body().byteStream());
                int len;
                byte[] buff = new byte[4096];
                StringBuilder result = new StringBuilder();
                while ((len = dis.read(buff)) != -1) {
                    result.append(new String(buff, 0, len));
                }

                String resultInfo = result.toString();
                Log.d("OkHttpDns", "Response: " + resultInfo);
             }
        });
    }
Important
  1. These best practices apply only to scenarios where you integrate the HTTPDNS Android SDK with OkHttp.

  2. For more information about how to use the domain name resolution service of the HTTPDNS Android SDK and how to integrate the HTTPDNS Android SDK, see the Android SDK Development Guide.

  3. For the complete sample code that shows the best practices for integrating the HTTPDNS Android SDK in an OkHttp framework scenario, see the Demo project source code.