すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud DNS:Android で OkHttp フレームワークを使用して DNS 名前解決時間と LocalDNS 名前解決結果を取得する

最終更新日:Nov 09, 2025

このドキュメントでは、Android でネットワークリクエストに okhttp ライブラリを使用する場合に、DNS 解決時間を取得する方法について説明します。

1. 概要

Android でネットワークリクエストに okhttp ライブラリを使用する場合、EventListener を介して DNS 解決時間を取得できます。 EventListener は、DNS 解決、接続確立、データ転送など、さまざまな段階でネットワークリクエストを追跡するための複数のコールバックメソッドを提供します。

Android では、InetAddress.getAllByName(String host) メソッドを使用して、ローカル DNS からの解決結果を取得できます。 これらの結果を予想される解決結果と比較して、ハイジャックがあるかどうかを判断できます。

2. DNS 解決時間を取得する方法

okhttpEventListener を使用して DNS 解決時間を取得する手順は次のとおりです。

ステップ 1:okhttp ライブラリをインポートする

ファイルに build.gradleokhttp 依存関係を追加してください。

implementation 'com.squareup.okhttp3:okhttp:4.9.3'

ステップ 2:カスタム EventListener を作成する

DNS 解決時間を監視および記録するために、カスタム EventListener クラスを作成する必要があります。

import okhttp3.EventListener;
import okhttp3.Call;
import okhttp3.HttpUrl;

public class DnsTimingEventListener extends EventListener {
    private long dnsStartTime;
    private long dnsEndTime;

    @Override
    public void dnsStart(Call call, String domainName) {
        super.dnsStart(call, domainName);
        dnsStartTime = System.currentTimeMillis();
    }

    @Override
    public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
        super.dnsEnd(call, domainName, inetAddressList);
        dnsEndTime = System.currentTimeMillis();
        long dnsDuration = dnsEndTime - dnsStartTime;
        System.out.println("DNS 解決時間: " + dnsDuration + " ミリ秒"); // 日本語訳を追加
    }
}

ステップ 3:OkHttpClient インスタンスを作成し、EventListener.Factory を設定する

カスタム EventListener ファクトリを OkHttpClient インスタンスに設定できます。

import okhttp3.OkHttpClient;

// OkHttpClient インスタンスを作成
OkHttpClient client = new OkHttpClient.Builder()
        .eventListenerFactory(new EventListener.Factory() {
            @Override
            public EventListener create(Call call) {
                return new DnsTimingEventListener();
            }
        })
        .build();

ステップ 4:ネットワークリクエストを実行する

構成済みの OkHttpClient インスタンスを使用して、ネットワークリクエストを実行できます。

import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;

public void executeNetworkRequest() {
    // Request オブジェクトを作成
    Request request = new Request.Builder()
    // .url() に実際の URL アドレスを設定します
            .url("https://www.example.com")
            .build();

    try {
        // リクエストを実行します
        Response response = client.newCall(request).execute();
        // レスポンスを処理します
        if (response.isSuccessful()) {
            System.out.println("リクエスト成功"); // 日本語訳を追加
            // ここでレスポンスデータを処理できます
        } else {
            System.out.println("リクエスト失敗、状態コード: " + response.code()); // 日本語訳を追加
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

上記の方法を使用して、DNS 解決時間を取得し、それに応じて処理できます。 これは、ネットワークリクエストの時間消費を理解するのに役立ち、パフォーマンスの最適化と監視に使用できます。

OkHttp DNS インターフェイスを実装して HTTPDNS サービスを使用できます。OkHttp DNS インターフェイスを実装して HTTPDNS を使用する場合、上記の方法で取得する名前解決時間は HTTPDNS の名前解決時間です。OkHttp DNS インターフェイスを実装しない場合、OkHttp はシステムのデフォルト DNS サービスである InetAddress を使用します。この場合、取得する名前解決時間はシステムの DNS サービスの名前解決時間です。

OkHttp の DNS インターフェースを実装するには、次のコードを参照できます。

  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 {
        // HTTPDNS Android SDK が提供する API を呼び出してドメイン名を解決
        String ip = null;
        String[] ipv4Array = mDNSResolver.getIpv4ByHostFromCache(hostname,true);
        if (ipv4Array != null && ipv4Array.length > 0) {
            ip = ipv4Array[0];
        }else {
            ip = mDNSResolver.getIPV4ByHost(hostname);
        }

        if (ip != null) {
            // IP が null でない場合は、ネットワークリクエストに直接使用
            Log.d(TAG, "mDnsCache の IP: " + ip);
            return Arrays.asList(InetAddress.getAllByName(ip));
        }
        // null が返された場合は、システムの DNS サービスを使用してドメイン名を解決
        return Dns.SYSTEM.lookup(hostname);
    }
}

3. LocalDNS 解決結果の取得とハイジャック検出比較の実行

次のコードを使用して、LocalDNS 解決結果を取得できます。

public List<String> getIPAddresses(String domain) {
    List<String> ipAddresses = new ArrayList<>();
    try {
        InetAddress[] addresses = InetAddress.getAllByName(domain);
        for (InetAddress address : addresses) {
            ipAddresses.add(address.getHostAddress());
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    return ipAddresses;
}

取得した LocalDNS 解決結果を、想定される解決結果と比較してハイジャックがあるかどうかを判断するには、次のコードを参照できます。

public boolean isDnsHijacked(String domain, List<String> expectedIps) {
      List<String> localIps = getIPAddresses(domain);
      if (localIps.isEmpty()) {
          return false; // ドメイン名を解決できません
      }
      for (String localIp : localIps) {
          if (!expectedIps.contains(localIp)) {
              return true; // 一致しない IP が見つかりました。DNS ハイジャックが存在する可能性があります
          }
      }
      return false; // すべての解決結果が一致しています
  }