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

Alibaba Cloud DNS:Android SDK 開発ガイド

最終更新日:Dec 13, 2025

このドキュメントでは、モバイル解決 HTTPDNS Android ソフトウェア開発キット (SDK) の統合方法について説明します。

概要

Android SDK は、モバイル解決 HTTPDNSDNS over HTTPS (DoH) JSON API をカプセル化しています。Android アプリがドメイン名を解決するための Java 関数インターフェイスを提供します。また、この SDK は、生存時間 (TTL) と Least Recently Used (LRU) ポリシーに基づいた効率的なドメイン名キャッシュも提供します。HTTPDNS を Android アプリに簡単に統合することで、ドメイン名の名前解決エラーを修正し、低コストで正確なトラフィックスケジューリングを実現できます。

この SDK には、以下の利点があります:

  • 使いやすさ

    SDK を統合して、モバイル解決 HTTPDNS サービスにアクセスできます。統合方法は簡単で、便利な名前解決サービスを提供します。

  • ゼロレイテンシー

    SDK には LRU キャッシュ機構が組み込まれています。各ドメイン名の名前解決から得られた IP アドレスをローカルにキャッシュします。また、SDK は TTL に基づいて期限切れのキャッシュをアクティブに更新し、キャッシュの有効性を保証します。これにより、ゼロレイテンシーのドメイン名解決が実現します。

詳細については、alidns_android_demo サンプルプロジェクトのソースコードをご参照ください。

SDK の統合

SDK のインポート

Gradle と Maven を使用した SDK の統合

build.gradle ファイルに次のコードを追加します:

allprojects {
  repositories {
    maven {
      url 'https://maven.aliyun.com/repository/public/'
    }
    mavenLocal()
    mavenCentral()
  }
}

参照ファイルの情報を追加します:

dependencies {
     implementation 'com.alibaba.pdns:alidns-android-sdk:2.2.8'
     implementation 'com.google.code.gson:gson:2.8.5'
}

AAR ファイルを使用した SDK の統合

alidns_android_sdk.aar ファイルをダウンロードします。詳細については、「SDK のダウンロード」をご参照ください。その後、AAR パッケージをプロジェクトの libs ディレクトリに追加できます。

説明

上記のいずれかの方法で SDK をプロジェクトに統合できます。

SDK の初期化

重要

SDK が期待どおりに動作し、IP アドレス解決の失敗を防ぐために、SDK はできるだけ早く初期化する必要があります。

コンソールから一意の Account ID を取得します。次に、キーを作成して、AccessKey IDAccessKey Secret を取得します。SDK を統合した後、初期化する必要があります。SDK の初期化の例については、Application クラスのコードをご参照ください。

public class DnsCacheApplication extends Application{

    private String accountId = "ご利用のアカウント ID"; // コンソールで SDK にアクセスするために使用するアカウント ID を設定します。
    private String accessKeyId = "ご利用の AccessKey ID"; // コンソールで SDK にアクセスするために使用する AccessKey ID を設定します。
    private String accessKeySecret = "ご利用の AccessKey Secret"; // コンソールで SDK にアクセスするために使用する AccessKey Secret を設定します。

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this,accountId,accessKeyId,accessKeySecret); // コンソールで SDK にアクセスするために使用するアカウント ID、AccessKey ID、AccessKey Secret を設定します。
       // 注:キャッシュに保持するドメイン名を設定すると、TTL の 75% が経過した時点で自動的に名前解決が開始されます。これにより、設定されたドメイン名の名前解決が常にキャッシュにヒットするようになります。ただし、CDN を使用している場合、TTL の値が小さくなる可能性があり、その結果、名前解決リクエストが増加し、コストが増大します。このメソッドは慎重に使用してください。
       DNSResolver.setKeepAliveDomains(new String[]{"キャッシュに保持するドメイン名 1","キャッシュに保持するドメイン名 2",...});       
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"事前解決するドメイン名 1","事前解決するドメイン名 2",...}); // IPv4 タイプの指定されたドメイン名を事前解決に設定します。事前解決ドメイン名を Alibaba Cloud DNS を使用して解決したいドメイン名に置き換えてください。
    }
}
説明

DNSResolver は、モバイル解決 HTTPDNS SDK のコアクラスです。このクラスは、モバイル解決 HTTPDNS が提供する DoH JSON API をカプセル化し、ターゲットドメイン名を対応する IP アドレスに解決します。モバイル解決 HTTPDNS SDK を使用するには、お使いの Android アプリの Application 子クラスに統合する必要があります。

また、Android プロジェクトで SDK を使用する際には、以下のアクセス権限を付与する必要があります:

<!--必要な権限-->
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
   <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

SDK 認証

この SDK は、バージョン 2.0 以降で認証をサポートしています。この機能は、ユーザー ID を保護し、不正なアクセスを防ぎます。認証を有効にするには、AccessKey IDAccessKey Secret を作成する必要があります。手順については、「キーの作成」をご参照ください。SDK の初期化中に認証パラメーターを設定しない場合、モバイル解決 HTTPDNSは名前解決リクエストを拒否します。この障害により、サービスが中断される可能性があります。このため、モバイル解決 HTTPDNS SDK を初期化する際に、認証パラメーターを設定する必要があります。

認証パラメーターは次のように設定できます。

DNSResolver.Init(this,accountId,accessKeyId,accessKeySecret);
警告
  • アプリの運用中に生成されるログやデータに Account ID、AccessKey ID、AccessKey Secret などのパラメーターが漏洩しないように、本番バージョンでは SDK デバッグログを無効にする必要があります。

  • 統合時に、コード内で Account ID、AccessKey ID、AccessKey Secret パラメーターを設定する必要があります。これらのパラメーターは、メータリングと課金に使用されます。悪意のある逆コンパイルによってこれらのパラメーターが取得され、情報漏洩につながるのを防ぐために、アプリを公開する前に難読化を有効にし、セキュリティ強化を適用する必要があります。

SDK 統合に関するよくある質問

Android 9.0 での HTTP リクエスト送信時の「cleartext HTTP traffic not permitted」エラー

原因:Android 9.0 (API レベル 28) 以降、Android はデフォルトでクリアテキストのネットワークアクセスを禁止し、HTTPS URL へのアクセスのみを許可しています。

解決策:

ご利用のアプリケーションの AndroidManifest.xml ファイルの <application> 要素に次のコードを追加します:

android:usesCleartextTraffic="true"

<application
        android:name=".DnsCacheApplication"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true">

Android 9.0 での「Didn't find class BasicHttpParams」エラー

原因:Apache HTTP クライアントは非推奨になりました。

Google は Android 6.0 で Apache HTTP クライアントのサポートを終了しました。Android 9.0 以降、org.apache.http.legacy は bootclasspath から削除されました。

この変更は、targetSdkVersion が 9.0 より前のほとんどのアプリケーションには影響しません。ただし、targetSdkVersion が 9.0 以降で、Apache HTTP インターフェイスを引き続き使用するか、これらのインターフェイスを使用するライブラリパッケージを参照するアプリケーションでは、Apache HTTP インターフェイスが見つからないというエラーが発生します。

解決策:

ご利用のアプリケーションの AndroidManifest.xml ファイルの <application> 要素に次のコードを追加します:

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

この SDK はバージョン 2.1.9 から JNI を導入しているため、アプリプロジェクトの開発環境で NDK を設定する必要があります。

  • アプリプロジェクトのルートディレクトリにある local.properties ファイルに NDK のインストールディレクトリを追加します。

ndk.dir=...\\ndk\\21.4.7075529; // ... は開発者が NDK をインストールしたローカルパスを示します。
  • アプリプロジェクトのルートディレクトリにある gradle.properties ファイルに次の設定を追加します。

android.useDeprecatedNdk = true;

アプリプロジェクトに NDK がすでに設定されている場合は、このステップを無視できます。SDK が期待どおりに動作することを保証するため、アプリのコンパイル時には JDK 1.8 と NDK 21.4.7075529 の使用を推奨します。

API リファレンス

共通設定

1. Init メソッドを使用した初期化

Application クラスで Init メソッドを呼び出して SDK を初期化できます。

DNSResolver.Init(this,accountId,accessKeyId,accessKeySecret);

2. 事前解決ドメイン名の設定

アプリケーションを初期化する際に、後で使用する可能性のあるドメイン名を モバイル解決 HTTPDNS SDK で事前登録することをお勧めします。これにより、SDK は事前にドメイン名を解決し、後続の名前解決リクエストのレイテンシーを削減できます。次のメソッドを呼び出して、事前解決ドメイン名を設定できます。

  • IPv6 または IPv4 ドメイン名の事前解決を指定できます。

// 事前解決のために指定されたドメイン名タイプを設定します。事前解決ドメイン名を Alibaba Cloud DNS を使用して解決したいドメイン名に置き換えてください。
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{...});

// DNSResolver.QTYPE_IPV4: 事前解決用の IPv4 レコードタイプ。
// DNSResolver.QTYPE_IPV6: 事前解決用の IPv6 レコードタイプ。
  • 現在のネットワークに基づいて、IPv6 または IPv4 ドメイン名の事前解決を自動的に選択できます。デュアルスタックネットワーク環境では、SDK は IPv6 と IPv4 の両方のドメイン名を事前解決します。

DNSResolver.getInstance().preLoadDomains(domains);
重要

事前解決インターフェイスは、リアルタイムで非同期ネットワークリクエストをトリガーします。このインターフェイスを呼び出す前に、必要な初期化設定が構成されていることを確認してください。

3. キャッシュに保持するドメイン名の設定

SDK は、設定されたドメイン名をキャッシュに保持することをサポートしています。TTL の 75% が経過すると、自動的に名前解決リクエストが開始されます。これにより、設定されたドメイン名の名前解決が常にキャッシュヒットとなり、SDK の名前解決パフォーマンスが向上します。この機能には、あまり多くのドメイン名を設定しないことを推奨します。現在の制限は 10 ドメイン名です。この機能は、事前解決とは独立して設定されます。

DNSResolver.setKeepAliveDomains(new String[]{"ユーザー指定のドメイン名 1", "ユーザー指定のドメイン名 2"});
説明

利点

1. TTL が切れる前にレコードをタイムリーに更新できます。

2. 事前解決と併用することで、最初の名前解決のレイテンシーを 0 ミリ秒に短縮できます。

欠点

1. TTL の 75% で再リクエストすると、追加料金が発生します。

4. サーバーサイドの IPv6 アドレスを使用するかどうかの指定

モバイル解決 HTTPDNS サービスは、IPv4 アドレスと IPv6 アドレスの両方からのアクセスをサポートします。DNSResolver.setEnableIPv6(boolean enable) メソッドを使用して、サーバー側の IPv6 アドレスを使用するかどうかを指定できます。このパラメーターを true に設定すると、SDK は IPv6 アドレスを使用してサーバーにアクセスします。false に設定した場合、または設定しなかった場合、SDK はデフォルトで IPv4 アドレスを使用します。IPv6 アクセスを有効にした状態で モバイル解決 HTTPDNS サービスに到達できない場合、SDK は自動的に IPv4 に切り替わり、リクエストを 1 回再試行します。

5. 最大キャッシュエントリ数の設定

DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); // 最大キャッシュエントリ数を設定します。デフォルト値:100。

最大値はカスタマイズできます。

6. サーバーアクセスプロトコルの設定

SDK では、DNS 解像度リクエストのプロトコルを HTTP または HTTPS に設定できます。 SDK は、HTTPS プロトコルの方が安全性が高いため、解像度での使用を推奨しています。 モバイル解決 HTTPDNS の課金は解像度リクエストの数に基づいており、HTTPS リクエストは HTTP リクエストの 5 倍の料金で課金されます。 要件に基づいてプロトコルを選択してください。

DNSResolver.setSchemaType(DNSResolver.HTTPS); // デフォルトのアクセスモードは HTTPS です。

DNSResolver.HTTP:HTTP 経由でサーバーサイドのインターフェイスにアクセスします。

DNSResolver.HTTPS:HTTPS 経由でサーバーサイドのインターフェイスにアクセスします。

7. ソケットベースの IP プロービングのポート番号の設定

DNSResolver.setSpeedPort(DNSResolver.PORT_80);

ソケットベースの IP プロービング用のポート番号を設定できます。デフォルトのポートは 80 です。

その他の詳細設定

1. SDK デバッグログの有効化/無効化

DNSResolver.setEnableLogger(true); // SDK のデバッグログは、デフォルトでは無効になっています。

SDK のデバッグログを有効にするかどうかを指定します。有効にするには true、無効にするには false を設定します。

2. LocalDNS への自動フォールバックを有効にするかどうかを、モバイル解決 HTTPDNS の名前解決が失敗した場合に指定します

DNSResolver.setEnableLocalDns(true); // デフォルトでは、HTTPDNS の解決に失敗した場合、LocalDNS への自動フォールバックが有効になっています。

3. ショートモードの有効化または無効化

モバイル解決 HTTPDNS の DNS over HTTPS(DoH) JSON API は、完全な JSON フォーマットまたは簡潔な IP アドレス配列フォーマットのいずれかでデータを返します。DNSResolver.setEnableShort(boolean enable) を呼び出して、ショートモードを有効化または無効化できます。デフォルトでは、ショートモードは無効になっています。例:

DNSResolver.setEnableShort(true); // デフォルト値は false です。このパラメーターを設定する必要はありません。
重要

ショートモードでは、モバイル解決 HTTPDNS サービスへの SDK 呼び出しは、簡略化された IP アドレス配列を返します。これにより応答データ量が削減されるため、ネットワークトラフィックに敏感なシナリオに最適です。

4. 無期限キャッシュの有効化

DNSResolver.setImmutableCacheEnable(false); // デフォルトでは、有効期限のないキャッシュは無効です。
重要

SDK には、3 つの内部キャッシュ更新メカニズムがあります:

  • 無期限キャッシュ:この機能を有効にすると、キャッシュはアプリの実行中ずっと有効と見なされます。キャッシュの有効期限チェックと更新は行われなくなります。setKeepAliveDomains を呼び出してキャッシュをアクティブに更新する必要はありません。これにより、名前解決の回数が最小限に抑えられます。

    メソッド:DNSResolver.setImmutableCacheEnable(boolean var0)

    パラメーターの説明:var0 パラメーターが true の場合、無期限キャッシュ機能が有効になります。var0false の場合、無期限キャッシュ機能は無効になります。

  • アクティブなキャッシュ更新:この機構は、名前解決リクエストが最新のキャッシュされた DNS レコードを使用することを保証するのに役立ちます。指定されたドメイン名の TTL が元の値の 75% に低下すると、SDK は自動的に新しい名前解決クエリをトリガーしてキャッシュを更新します。これにより、後続のリクエストの DNS レイテンシーが削減され、特にドメイン名の権威ゾーンが変更された場合にキャッシュを最新の状態に保つのに役立ちます。アクティブな更新用に設定するドメイン名の数を制限することを推奨します。最大 10 ドメイン名がサポートされています。

    メソッド:DNSResolver.setKeepAliveDomains(String[] var1)

    パラメーターの説明:var1 は、アクティブな更新が必要なドメイン名文字列の配列です。

  • パッシブキャッシュ更新

    次の 2 つのメソッドを呼び出して名前解決の結果を取得すると、キャッシュはパッシブに更新されます:

    • getIPsV4ByHost(String hostName) メソッド:hostName に対応する IPv4 レコード配列を取得します。キャッシュが空でなく、レコードが期限切れでない場合、キャッシュされた結果が返されます。それ以外の場合、メソッドはネットワークリクエストを通じて最新の名前解決結果を取得し、結果を返してからキャッシュを更新します。このメソッドは、名前解決結果の高い精度が要求されるシナリオでよく使用されます。

    • getIpv4ByHostFromCache(String hostName, boolean isAllowExp) メソッド:キャッシュから hostName に対応する IPv4 レコード配列を取得します。このメソッドは、isAllowExp パラメーターの値に基づいて、キャッシュから期限切れの名前解決結果を返すかどうかを決定します。アプリの起動時に preload メソッドと組み合わせてこのメソッドを使用することを推奨します。これにより、アプリが起動時に最新の名前解決結果をキャッシュすることが保証されます。

      isAllowExp が true に設定されている場合、キャッシュが期限切れであっても、古いレコードが返されます。キャッシュが空の場合、null が返されます。isAllowExpfalse に設定されている場合、キャッシュが期限切れか空であれば null が返されます。どちらの場合でも、キャッシュを更新するために非同期リクエストが送信されます。

    推奨例

    String[] IPArray = mDNSResolver.getIpv4ByHostFromCache(hostname,true);
            if (IPArray == null || IPArray.length == 0){
                IPArray = mDNSResolver.getIPsV4ByHost(hostname);
            }

5. キャッシュの設定

DNSResolver.setEnableCache(true); // デフォルトでキャッシュは有効です。

キャッシュ機能を有効にするかどうかを指定します。キャッシュを有効にするには true、無効にするには false を設定します。

6. IP 速度テストの有効化

DNSResolver.setEnableSpeedTest(false); // デフォルトで IP 速度テストは無効になっています。

IP 速度テスト機能を有効にするかどうかを指定します。値が true の場合は機能を有効にし、false の場合は無効にします。

7. ドメイン名の ISP 別のキャッシュの設定

DNSResolver.setIspEnable(true);// ISP ベースのドメイン名キャッシュを有効にするかどうかを指定します。

`setIspEnable` が `true` に設定されている場合、各ネットワーク環境 (ISP) は解決結果用に独自のキャッシュを持ちます。それ以外の場合、すべてのネットワーク環境が 1 つのキャッシュを共有します。

8. 最大ネガティブキャッシュ TTL の設定

DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE);// ネガティブキャッシュの最大 TTL を設定します。デフォルトは 30 秒です。

ネガティブキャッシュは、IP アドレスに解決できないドメイン名に対する応答を保存します。必要に応じて、このキャッシュの最大 TTL を設定できます。

9. 最大キャッシュ TTL の設定

DNSResolver.setMaxTtlCache(MAX_TTL_CACHE);// キャッシュの最大 TTL を設定します。デフォルトは 3600 秒です。

SDK を使用して、すべてのキャッシュされたエントリの最大 TTL を設定できます。デフォルトは 3600 秒です。

10. クライアントサブネット情報の設定

DNSResolver.setEdnsSubnet("1.2.XX.XX/24");

`setEdnsSubnet` パラメーターは、DNS の拡張メカニズム (EDNS) クライアントサブネット (ECS) 機能 (RFC 7871) をサポートします。この機能は、サブネット情報を権威 DNS サーバに送信して、より正確な DNS 名前解決とトラフィックの再ルーティングを実現します。長いマスクはより正確なアドレス情報を提供し、短いマスクはより優れたユーザープライバシーを提供します。マスク長は /24 を推奨します。

説明

DNS over HTTPS (DoH) JSON API を使用する DNS プロキシのシナリオでは、DNS プロキシはこのパラメーターを使用してユーザーのサブネット情報を モバイル解決 HTTPDNS に渡します。そしてそれが、その情報を権威サーバーに転送します。

例えば、`DNSResolver.setEdnsSubnet("1.2.XX.XX/24")` が呼び出されると、権威サーバーは `1.2.XX.XX/24` のアドレスプレフィックスを使用して、最適化された名前解決の結果を提供します。

11. 名前解決タイムアウトの設定

timeout プロパティは、名前解決のタイムアウトを指定します。デフォルト値は 3 秒です。2 秒から 5 秒の範囲でカスタム値を設定できます。

DNSResolver.setTimeout(3);

12. トラブルシューティング用のセッション ID の取得

sessionId パラメーターは、アプリが起動する時に生成され、そのライフサイクルを通じて一定に保たれます。アプリのライフサイクル中に行われるすべての モバイル解決 HTTPDNS 名前解決リクエストには、この sessionId が含まれます。サーバーはこのパラメーターを記録し、インデックスを生成します。sessionId を使用して、アプリのライフサイクルをトラックし、関連する問題のトラブルシューティングを行うことができます。

public static String getSessionId()

13. コールバックのロギング

SDK が生成したログを受信するコールバック

HttpDnsLog.setLogger(new ILogger() {
  @Override
  public void log(String msg) {
      Log.d("HttpDnsLogger:", msg);
  }
});

逆難読化の構成

   -keep class com.alibaba.pdns.** {*;}

サービス API

  /**
   * 現在のネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) を自動的に検出し、ドメイン名の名前解決をプリロードします。
   * デュアルスタック環境では、このメソッドは IPv4 と IPv6 両方の名前解決結果をプリロードします。
   * アプリケーションの起動時に SDK の初期化処理でこのメソッドを呼び出して、名前解決の結果をキャッシュに保存します。
   * これにより、後続のドメイン名解決におけるレイテンシーを短縮できます。
   *
   * @param domains プリロードするドメイン名。
   */
   public void preLoadDomains(final String[] domains)

    /**
     * 指定された IPv4 または IPv6 のドメイン名をプリロードします。
     * アプリケーションの起動時に SDK の初期化処理でこのメソッドを呼び出して、名前解決の結果をキャッシュに保存します。
     * これにより、後続のドメイン名解決におけるレイテンシーを短縮できます。
     *
     * @param qType プリロードする IP アドレスのタイプ (IPv4 または IPv6)。
     * @param domains プリロードするドメイン名。
     */
    public void preLoadDomains(String qType, final String[] domains)
   /**
   * 現在のネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) を自動的に検出し、ドメイン名の名前解決データを取得します。
   * キャッシュに有効な名前解決結果が存在する場合、キャッシュされた結果が返されます。
   * キャッシュが空であるか、結果が期限切れの場合、このメソッドはサーバーに同期ネットワークリクエストを送信して再帰的な名前解決結果を取得します。
   * その後、取得した結果を返し、キャッシュに保存します。
   *
   * @param host 名前解決するドメイン名。
   * @return 現在のネットワーク環境に基づいた最適な IP アドレスの配列。
   */
    public String[] getIpsByHost(String host)

/**
    * ホスト名の IPv4 レコードの配列を取得します。
    * キャッシュに有効な名前解決結果が存在する場合、キャッシュされた結果が返されます。
    * キャッシュが空であるか、結果が期限切れの場合、このメソッドはサーバーに同期ネットワークリクエストを送信して再帰的な名前解決結果を取得します。
    * その後、取得した結果を返し、キャッシュに保存します。
    *
    * @param hostName 名前解決するホスト名 (例:www.taobao.com)。
    * @return 指定されたホスト名の IPv4 アドレスの配列。
    */
  public  String[] getIPsV4ByHost(String hostName) 

   /**
    * ホスト名の IPv6 レコードの配列を取得します。
    * @param hostName 名前解決するホスト名 (例:www.taobao.com)。
    * @return 指定されたホスト名の IPv6 アドレスの配列。
    */
  public String[] getIPsV6ByHost(String hostName) 

  

  /**
   * 現在のネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) を自動的に検出し、キャッシュから解決済みの IP アドレスの配列を取得します。
   * キャッシュが空の場合、このメソッドは null を返し、非同期クエリを開始します。
   * クエリ結果はその後キャッシュに保存されます。
   * キャッシュされた結果が存在し、期限切れの結果を返すことが許可されている場合、このメソッドは期限切れの IP アドレスを返し、非同期でキャッシュを更新します。
   * 期限切れの結果を返すことが許可されておらず、キャッシュされた結果が期限切れの場合、このメソッドは null を返し、非同期でキャッシュを更新します。
   *
   * @param host クエリ対象のホスト (例:www.taobao.com)。
   * @param isAllowExp 期限切れの名前解決データを返すかどうかを指定します。
   * @return キャッシュから取得したホストの解決済み IP アドレスの配列。
   */
   public String[] getIpsByHostFromCache(String host, boolean isAllowExp)
   
    /**
     * キャッシュから解決済みの IPv4 アドレスの配列を取得します。
     * キャッシュが空の場合、このメソッドは null を返し、非同期クエリを開始します。
     * クエリ結果はその後キャッシュに保存されます。
     * キャッシュされた結果が存在し、期限切れの結果を返すことが許可されている場合、このメソッドは期限切れの IP アドレスを返し、非同期でキャッシュを更新します。
     * 期限切れの結果を返すことが許可されておらず、キャッシュされた結果が期限切れの場合、このメソッドは null を返し、非同期でキャッシュを更新します。
     *
     * @param host クエリ対象のホスト (例:www.taobao.com)。
     * @param isAllowExp 期限切れの名前解決データを返すかどうかを指定します。
     * @return キャッシュから取得したホストの解決済み IPv4 アドレスの配列。
     */
    private String[] getIpv4ByHostFromCache(String host , boolean isAllowExp)

    /**
     * キャッシュから解決済みの IPv6 アドレスの配列を取得します。
     * キャッシュが空の場合、このメソッドは null を返し、非同期クエリを開始します。
     * クエリ結果はその後キャッシュに保存されます。
     * キャッシュされた結果が存在し、期限切れの結果を返すことが許可されている場合、このメソッドは期限切れの IP アドレスを返し、非同期でキャッシュを更新します。
     * 期限切れの結果を返すことが許可されておらず、キャッシュされた結果が期限切れの場合、このメソッドは null を返し、非同期でキャッシュを更新します。
     *
     * @param host クエリ対象のホスト (例:www.taobao.com)。
     * @param isAllowExp 期限切れの名前解決データを返すかどうかを指定します。
     * @return キャッシュから取得したホストの解決済み IPv6 アドレスの配列。
     */
    private String[] getIpv6ByHostFromCache(String host , boolean isAllowExp)

  /**
  * URL に対応する IPv4 レコードの DomainInfo オブジェクトの配列を取得します。
  * キャッシュに有効な名前解決結果が存在する場合、キャッシュされた結果が返されます。
  * キャッシュが空であるか、結果が期限切れの場合、このメソッドはサーバーに同期ネットワークリクエストを送信して再帰的な名前解決結果を取得します。
  * その後、取得した結果を返し、キャッシュに保存します。
  *
  * @param url URL (例:http://www.taobao.com)。
  * @return ターゲット URL の IPv4 タイプの DomainInfo オブジェクトの配列。
  */
  public DomainInfo[] getIPsV4DInfoByUrl(String url) 

  注:DomainInfo オブジェクトの url は、ホストがすでに IP アドレスに置き換えられた URL です。手動で URL を変更する必要はありません。

  /**
   * URL に対応する IPv6 レコードの DomainInfo オブジェクトの配列を取得します。
   * キャッシュに有効な名前解決結果が存在する場合、キャッシュされた結果が返されます。
   * キャッシュが空であるか、結果が期限切れの場合、このメソッドはサーバーに同期ネットワークリクエストを送信して再帰的な名前解決結果を取得します。
   * その後、取得した結果を返し、キャッシュに保存します。
   * 
   * @param url URL (例:http://m.taobao.com)。
   * @return ターゲット URL の IPv6 タイプの DomainInfo オブジェクトの配列。
   */
   public DomainInfo[] getIPsV6DInfoByUrl(String url) 

  /**
    * URL に対応する IPv4 レコードの DomainInfo オブジェクトを取得します。
    * キャッシュに有効な名前解決結果が存在する場合、キャッシュされた結果が返されます。
    * キャッシュが空であるか、結果が期限切れの場合、このメソッドはサーバーに同期ネットワークリクエストを送信して再帰的な名前解決結果を取得します。
    * その後、取得した結果を返し、キャッシュに保存します。
    *
    * @param url URL (例:http://m.taobao.com)。
    * @return ターゲット URL の IPv4 タイプのオブジェクトのコレクションからランダムに選択された DomainInfo オブジェクト。
    */
    public DomainInfo getIPV4DInfoByUrl(String url) 


  /**
    * URL に対応する IPv6 レコードの DomainInfo オブジェクトを取得します。
    * キャッシュに有効な名前解決結果が存在する場合、キャッシュされた結果が返されます。
    * キャッシュが空であるか、結果が期限切れの場合、このメソッドはサーバーに同期ネットワークリクエストを送信して再帰的な名前解決結果を取得します。
    * その後、取得した結果を返し、キャッシュに保存します。
    *
    * @param url URL (例:http://www.taobao.com)。
    * @return ターゲット URL の IPv6 タイプのオブジェクトのコレクションからランダムに選択された DomainInfo オブジェクト。
    */
   public DomainInfo getIPV6DInfoByUrl(String url) 

   説明:返される domainInfo オブジェクトは、次のプロパティをカプセル化します。

  /**
   * ドメイン名の自動インクリメント ID。
    */
    public String id = null;

   /**
    * ホスト部分が IP アドレスに置き換え済みの、すぐに使用可能な URL。
    */
     public String url = null;

    /**
    * HTTP リクエストヘッダーに設定するターゲットサービス名。
    */
    public String host = "";

   /**
    * 応答のコンテンツ本文。
    */
   public String data = null;

   /**
    * リクエストが開始された時間。
    */
   public String startTime = null;

   /**
    * リクエストが終了した時間。リクエストがタイムアウトした場合、この値は null になります。
    */
   public String stopTime = null; 

   /**
   * サーバーから返されるステータスコード (例:200、404、500)。
   */
   public String code = null;

  /**
    * ホスト名の IPv4 レコードを取得します。
    * キャッシュに有効な名前解決結果が存在する場合、キャッシュされた結果が返されます。
    * キャッシュが空であるか、結果が期限切れの場合、このメソッドはサーバーに同期ネットワークリクエストを送信して再帰的な名前解決結果を取得します。
    * その後、取得した結果を返し、キャッシュに保存します。
  
    * @param hostName 名前解決するホスト名 (例:www.taobao.com)。
    * @return ターゲットホスト名のアドレスセットからランダムに選択された IPv4 アドレス。
    *         速度テストが有効な場合、このメソッドは最適な IPv4 アドレスを返します。
    */
  public String getIPV4ByHost(String hostName) 

   /**
    * ホスト名の IPv6 レコードを取得します。
    * キャッシュに有効な名前解決結果が存在する場合、キャッシュされた結果が返されます。
    * キャッシュが空であるか、結果が期限切れの場合、このメソッドはサーバーに同期ネットワークリクエストを送信して再帰的な名前解決結果を取得します。
    * その後、取得した結果を返し、キャッシュに保存します。
  
    * @param hostName 名前解決するホスト名 (例:www.taobao.com)。
    * @return ターゲットホスト名のアドレスセットからランダムに選択された IPv6 アドレス。
    *         速度テストが有効な場合、このメソッドは最適な IPv6 アドレスを返します。
    */
   public String getIPV6ByHost(String hostName) 
      

    /**
     * HTTPDNS へのリクエストの成功および失敗の統計を取得します。
     *
     * @return すべてのドメイン名の名前解決統計を含む JSON 配列文字列。
     */
    public String getRequestReportInfo()
    
     /**
     * キャッシュを維持するドメイン名を設定します。
     * 指定されたドメイン名は、TTL の 75% が経過すると自動的に解決されます。
     * これにより、これらのドメイン名の名前解決リクエストが常にキャッシュにヒットし、SDK の名前解決効率が向上します。
     * この機能に設定するドメイン名は多すぎないようにしてください。現在の制限は 10 です。
     * この構成は事前解決とは独立しています。
     *
     * @param persistentCacheDomains
     */
    public synchronized static void setKeepAliveDomains(String[] persistentCacheDomains) {
    
     /**
     * 指定されたドメイン名のキャッシュをクリアします。`domains` パラメーターが null の場合、
     * すべてのドメイン名のキャッシュがクリアされます。
     *
     * @param domains キャッシュエントリを削除するドメイン名の配列。
     */
    public void clearHostCache(String[] domains){

API 呼び出しの例

URL:名前解決する URL。例:http://www.taobao.com。

 String hostname = "www.taobao.com";
 String url = "http://www.taobao.com";

1. 現在のネットワーク環境に最適な IP データを取得

String[] ip = DNSResolver.getInstance().getIpsByHost(hostname); // 現在のネットワークのドメイン名名前解決から最適な IP アドレスを取得します。

2. 現在のネットワーク環境のドメイン名名前解決をプリロード

DNSResolver.getInstance().preLoadDomains(domains); // 事前解決するドメイン名を設定します。プリロードされたドメイン名を、Alibaba Cloud DNS を使用して名前解決したいドメイン名に置き換えます。

3. 現在のネットワーク環境でキャッシュされたドメイン名の名前解決を取得

String[] ip = DNSResolver.getInstance().getIpsByHostFromCache(hostname,true);// 現在のネットワーク環境のキャッシュからドメイン名の名前解決データを取得します。

4. IPv4 アドレスの取得

String IPV4 = DNSResolver.getInstance().getIPV4ByHost(hostname); // ドメイン名の名前解決から IPv4 アドレスを取得します。

5. IPv6 アドレスの取得

String IPV6 =  DNSResolver.getInstance().getIPV6ByHost(hostname); // ドメイン名の名前解決から IPv6 アドレスを取得します。

6. キャッシュから名前解決された IPv4 アドレスを取得

String[] IPV4 =  DNSResolver.getInstance().getIpv4ByHostFromCache(hostname , true); // キャッシュから名前解決済みの IPv4 アドレスを取得します。

7. キャッシュから名前解決された IPv6 アドレスを取得

String[] IPV6 =  DNSResolver.getInstance().getIpv6ByHostFromCache(hostname , true); // キャッシュから名前解決済みの IPv6 アドレスを取得します。

8. URL による DomainInfo オブジェクトの取得

DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(url); // 置き換えられた URL を取得します。

9. 特定のドメイン名の名前解決キャッシュをクリア

DNSResolver.getInstance().clearHostCache(hostName); // 指定されたドメイン名のキャッシュをクリアします。すべてのドメイン名のキャッシュをクリアするには、hostName を null に設定します。

10. Alibaba Cloud DNS リクエストの成功と失敗に関する統計を取得

String reportInfo = DNSResolver.getInstance().getRequestReportInfo(); // 成功したリクエストと失敗したリクエストに関する統計を取得します。

次の表は、ドメイン名の名前解決に関する統計の JSON 配列内のフィールドについて説明しています:

 [
      {
         "avgRtt":"1",                         // ドメイン名の名前解決の平均時間。単位:ms。
         "degradeLocalDnsCount": 0,            // サービスが LocalDNS にダウングレードされた回数。                       
         "domainName":"www.example.com",       // 名前解決されたドメイン名。
         "hitDnsCacheCount": 1,                // キャッシュヒット数。
         "httpabnormalCount": 0,               // 失敗した再帰的リクエストの数。
         "isp": "China Mobile",                // キャリア名。
         "localDnsResolveErrCount": 0,         // 失敗した LocalDNS の名前解決の数。
         "maxRtt": 8.0,                        // ドメイン名の名前解決の最大時間。単位:ms。          
         "nonetworkCount": 0,                  // ネットワークが利用不可だった回数。
         "permissionErrCount": 0,              // 失敗したユーザー認証の数。
         "queryType": 1,                       // IP アドレスタイプ。1 は IPv4 を、28 は IPv6 を示します。
         "recursiveReqCount": 1,               // 再帰的クエリの数。
         "reqParameterErrCount": 0,            // リクエストパラメーターのフォーマットが無効だった回数。
         "reqPathErrCount": 0,                 // URL エラーの数。
         "reqServerErrCount": 0,               // DNS サーバーエラーの数。
         "reqTimeoutCount": 0,                 // DNS サービスのタイムアウト数。
         "resolveSuccessCount": 1,             // 成功した名前解決の数。
         "timeoutCount": 0,                    // ネットワークタイムアウトの数。
         "utfNetWorkErroNum": 0                // データレポートのタイムアウト数。
      }
         ......
 ]
重要

モバイル解決 HTTPDNS の名前解決の統計は、ネットワーク環境、ドメイン名、リクエストタイプのディメンションで確認できます。

public class MainActivity extends AppCompatActivity {
   private Button button;
   private TextView tvInfo;
   private TextView tvResult;
   private String hostUrl = "http://www.taobao.com"; // 名前解決したい hostUrl に置き換えてください。
   private String hostName = "www.taobao.com"; // 名前解決したい hostName に置き換えてください。
   private static final String TAG = "PDnsDemo";
   private static ExecutorService pool = Executors.newSingleThreadExecutor();
   private static final String PDNS_RESULT = "pdns_result";
   private static final int SHOW_CONSOLE_TEXT = 10000;
   private Handler mHandler;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.demo_activity_main);
       init();
       initHandler();
   }
 private void init() {
       tvInfo = findViewById(R.id.tv_respons_info);
       tvResult = findViewById(R.id.tv_respons);
       button = findViewById(R.id.btn_onclik);
       button.setOnClickListener(new View.OnClickListener() {
           public void onClick(View view) {
               new Thread(new Runnable() {
                      @Override
                      public void  run() {
                      // HTTPDNS SDK の getIPV4ByHost メソッドを呼び出して、ターゲットドメイン名が名前解決された後の IP アドレスを取得します。
                      String ip = DNSResolver.getInstance().getIPV4ByHost(hostName);
                      if(ip != null){
                         tvInfo.setText("The IP address of the resolved domain name is: "+ ip);
                      }
                      // HTTPDNS SDK の getIPV4DInfoByUrl メソッドを呼び出して、ターゲットドメイン名が名前解決された後の domainInfo オブジェクトから URL を取得します。この URL では、元の URL のホストが IP アドレスに置き換えられています。
                      DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(hostUrl);
                      if (dinfo != null) {
                           showResponse(dinfo);
                      }
                   }
               }).start();
           }
       });
   }
   private void initHandler() {
       mHandler = new Handler() {
           @Override
           public void handleMessage(Message msg) {
               switch (msg.what)  {
                   case SHOW_CONSOLE_TEXT:
                       tvResult.setText(msg.getData().getString(PDNS_RESULT) + "\n");
                       break;
               }
           }
       };
   }
   private void showResponse(final DomainInfo dinfo) {
                // ネットワークリクエストを送信します。
               String requestUrl = dinfo.url;
               HttpURLConnection conn = null;
               try {
                   URL url = new URL(requestUrl);
                   conn = (HttpURLConnection) url.openConnection();
                   // IP アドレスを使用してアクセスする場合、HTTP リクエストヘッダーの Host フィールドを名前解決されたドメイン名に設定します。
                   conn.setRequestProperty("Host", url.getHost());// HTTP リクエストヘッダーの Host フィールドを設定します。
                   DataInputStream dis = new DataInputStream(conn.getInputStream());
                   int len;
                   byte[] buff = new byte[4096];
                   StringBuilder response = new StringBuilder();
                   while ((len = dis.read(buff)) != -1) {
                       response.append(new String(buff, 0, len));
                   }
                   Log.d(TAG, "Response: " + response.toString());
                   dis.close();
                   sendMessage(response.toString());
               } catch (IOException e) {
                   e.printStackTrace();
               }finally {
                   if (conn != null) {
                       conn.disconnect();
                   }
               }
           }
   private void sendMessage(String message) {
       if (mHandler != null) {
               Message msg = mHandler.obtainMessage();
               Bundle bundle = new Bundle();
               bundle.putString(PDNS_RESULT, message);
               msg.setData(bundle);
               msg.what = SHOW_CONSOLE_TEXT;
               mHandler.sendMessage(msg);
       }
   }
}

public class DnsCacheApplication extends Application {
    
    private String accountId = "Your Account ID"; // コンソールで SDK と統合するために使用するアカウント ID を設定します。
    private String accessKeyId = "Your AccessKey ID"; // コンソールで SDK と統合するために使用する AccessKey ID を設定します。
    private String accessKeySecret = "Your AccessKey secret"; // コンソールで SDK と統合するために使用する AccessKey Secret を設定します。

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this, accountId, accessKeyId, accessKeySecret); // コンソールでの SDK 統合のために、アカウント ID、AccessKey ID、AccessKey Secret を設定します。
       DNSResolver.setKeepAliveDomains(new String[]{"your-domain-1","your-domain-2",...}); // キープアライブドメインを設定すると、TTL の 75% が経過した時点で名前解決が自動的に開始されます。これにより、設定されたドメイン名の名前解決リクエストが常にキャッシュにヒットするようになります。
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"your-preload-domain-1","your-preload-domain-2",...}); // IPv4 タイプのドメイン名を事前解決します。事前読み込みされたドメイン名を、Alibaba Cloud DNS を使用して名前解決したいドメイン名に置き換えます。
    }
}

注意事項

  1. モバイル解決 HTTPDNS を使用してドメイン名を IP アドレスに解決した後、その IP アドレスを使用してアプリケーションリクエストを送信します。HTTP リクエストヘッダーの Host フィールドは、元のドメイン名に設定してください。

  2. サービスが正常に動作することを保証するために、モバイル解決 HTTPDNS SDK がドメイン名に対して空の IP アドレスを返した場合は、元のドメイン名を使用してリクエストを行うようにフォールバックする必要があります。以下のコードは、その一例です。

    String ip = DNSResolver.getInstance().getIPV4ByHost("domain name");
    if (ip != null) {
    	// URL 内のホストを IP アドレスに置き換えて、インターフェイスリクエストを送信します。
    }else {
    	// 代替リクエストとして、元のドメイン名のリクエスト URL を使用します (ネットワークリクエストには、ドメイン名を含む元の URL を使用します)。
    }
  3. モバイル解決 HTTPDNS SDK をすぐに使い始めるためのデモプログラムが用意されています。ここをクリックして、デモプログラムをダウンロードしてください。

  4. SDK を統合した後、コンソールの [トラフィック分析] セクションでトラフィックを確認し、統合を検証してください。トラフィックが生成されない場合は、アカウント IDAccessKey ID、および AccessKey Secret パラメーターが正しく設定されていることを確認してください。