All Products
Search
Document Center

Alibaba Cloud DNS:Android SDK development guide

Last Updated:Dec 12, 2025

This document describes how to integrate the HTTPDNS Android software development kit (SDK).

Overview

The Android SDK encapsulates the DNS over HTTPS (DoH) JSON API of HTTPDNS. It provides Java function interfaces for Android apps to resolve domain names. The SDK also offers an efficient domain name cache based on time-to-live (TTL) and Least Recently Used (LRU) policies. You can easily integrate HTTPDNS into your Android apps to fix domain name resolution errors and achieve precise traffic scheduling at a low cost.

The SDK provides the following benefits:

  • Easy to use

    You can integrate the SDK to access the HTTPDNS service. The integration method is simple and provides a convenient resolution service.

  • Zero latency

    The SDK has a built-in LRU caching mechanism. It caches the IP address from each domain name resolution locally. The SDK also actively updates the expired cache based on TTL to ensure the cache is valid. This helps you achieve zero-latency domain name resolution.

For more information, see the alidns_android_demo sample project source code.

SDK integration

Import the SDK

Integrate the SDK using Gradle with Maven

Add the following code to the build.gradle file:

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

Add the information for the referenced file:

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

Integrate the SDK using an AAR file

Download the alidns_android_sdk.aar file. For more information, see Download the SDK. Then, you can add the AAR package to the libs directory of your project.

Note

You can use either of the preceding methods to integrate the SDK into your project.

Initialize the SDK

Important

To ensure that the SDK works as expected and prevent IP address resolution failures, you must initialize the SDK as early as possible.

Obtain your unique Account ID from the console. Then, create a key to obtain your AccessKey ID and AccessKey Secret. After you integrate the SDK, you must initialize it. For an example of SDK initialization, see the code in the Application class.

public class DnsCacheApplication extends Application{

    private String accountId = "Your Account ID"; // Set the Account ID that you use to access the SDK in the console.
    private String accessKeyId = "Your AccessKey ID"; // Set the AccessKey ID that you use to access the SDK in the console.
    private String accessKeySecret = "Your AccessKey secret"; // Set the AccessKey secret that you use to access the SDK in the console.

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this,accountId,accessKeyId,accessKeySecret); // Set the Account ID, AccessKey ID, and AccessKey secret that you use to access the SDK in the console.
       // Note: If you configure domain names to be kept in the cache, resolution is automatically initiated when 75% of the TTL elapses. This ensures that the resolution of configured domain names always hits the cache. However, if you use a CDN, the TTL value may be small. This results in many resolution requests and increases costs. Use this method with caution.
       DNSResolver.setKeepAliveDomains(new String[]{"The domain name to be kept in the cache 1","The domain name to be kept in the cache 2",...});       
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"The domain name to be pre-resolved 1","The domain name to be pre-resolved 2",...}); // Set the specified domain names of the IPv4 type for pre-resolution. Replace the pre-resolution domain names with the domain names that you want to resolve using Alibaba Cloud DNS.
    }
}
Note

DNSResolver is the core class of the HTTPDNS SDK. It encapsulates the DoH JSON API provided by HTTPDNS and resolves a target domain name to the corresponding IP address. To use the HTTPDNS SDK, you must integrate it into the Application child class of your Android app.

In addition, when you use the SDK in an Android project, you must grant the following access permissions:

<!--Required permissions-->
   <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 authentication

This SDK supports authentication in version 2.0 and later. This feature secures user identities and prevents unauthorized access. To enable authentication, you must create an AccessKey ID and an AccessKey Secret. For instructions, see Create a key. If you do not set authentication parameters during SDK initialization, HTTPDNS rejects domain name resolution requests. This failure may disrupt your services. Therefore, you must set authentication parameters when you initialize the HTTPDNS SDK.

You can set the authentication parameters as follows:

DNSResolver.Init(this,accountId,accessKeyId,accessKeySecret);
Warning
  • To prevent parameters such as Account ID, AccessKey ID, and AccessKey secret from being leaked in logs or data generated during app operation, you must disable SDK debugging logs in the production version.

  • You must set the Account ID, AccessKey ID, and AccessKey secret parameters in the code during integration. These parameters are used for metering and billing. To prevent these parameters from being obtained through malicious decompilation, which can cause information leakage, you must enable obfuscation and apply security hardening to your app before you publish it.

FAQ for SDK integration

The "cleartext HTTP traffic not permitted" error is reported when you send an HTTP request on Android 9.0

Cause: Starting from Android 9.0 (API level 28), Android prohibits cleartext network access by default and allows access only to HTTPS URLs.

Solution:

Add the following code to the <application> element in the AndroidManifest.xml file of your 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">

The "Didn't find class BasicHttpParams" error is reported on Android 9.0

Cause: The Apache HTTP client is deprecated.

Google removed support for the Apache HTTP client in Android 6.0. Starting from Android 9.0, org.apache.http.legacy has been removed from the bootclasspath.

This change does not affect most applications that have a targetSdkVersion earlier than 9.0. However, applications that have a targetSdkVersion of 9.0 or later and continue to use Apache HTTP interfaces or reference library packages that use these interfaces will receive an error indicating that the Apache HTTP interfaces cannot be found.

Solution:

Add the following code to the <application> element in the AndroidManifest.xml file of your application:

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

This SDK introduces the JNI starting from version 2.1.9. You must configure the NDK in the development environment of your app project.

  • Add the NDK installation directory to the local.properties file in the root directory of your app project.

ndk.dir=...\\ndk\\21.4.7075529; // ... indicates the local path where the developer installed the NDK.
  • Add the following configuration to the gradle.properties file in the root directory of your app project.

android.useDeprecatedNdk = true;

If the NDK is already configured for your app project, you can ignore this step. To ensure that the SDK works as expected, we recommend that you use JDK 1.8 and NDK 21.4.7075529 when you compile your app.

API reference

Common settings

1. Initialize using the Init method

You can call the Init method in your Application class to initialize the SDK.

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

2. Set pre-resolution domain names

When you initialize your application, we recommend that you pre-register the domain names that you may use later with the HTTPDNS SDK. This allows the SDK to resolve the domain names in advance and reduces the latency of subsequent domain name resolution requests. You can call the following method to set pre-resolution domain names:

  • You can specify pre-resolution for IPv6 or IPv4 domain names.

// Set the specified domain name type for pre-resolution. Replace the pre-resolution domain names with the domain names that you want to resolve using Alibaba Cloud DNS.
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{...});

// DNSResolver.QTYPE_IPV4: The IPv4 record type for pre-resolution.
// DNSResolver.QTYPE_IPV6: The IPv6 record type for pre-resolution.
  • You can automatically select pre-resolution for IPv6 or IPv4 domain names based on the current network. In a dual-stack network environment, the SDK pre-resolves both IPv6 and IPv4 domain names.

DNSResolver.getInstance().preLoadDomains(domains);
Important

The pre-resolution interface triggers asynchronous network requests in real time. You must make sure that the required initialization settings are configured before you call this interface.

3. Set domain names to keep in the cache

The SDK supports keeping configured domain names in the cache. A resolution request is automatically initiated when 75% of the TTL elapses. This ensures that the resolution of configured domain names always results in a cache hit and improves the resolution performance of the SDK. We recommend that you do not set too many domain names for this feature. The current limit is 10 domain names. This feature is configured independently of pre-resolution.

DNSResolver.setKeepAliveDomains(new String[]{"User-specified domain name 1", "User-specified domain name 2"});
Note

Benefits

1. Records can be updated in a timely manner before the TTL expires.

2. When used with pre-resolution, this feature can reduce the latency of the first resolution to 0 milliseconds.

Drawbacks

1. Re-requesting at 75% of the TTL incurs additional fees.

4. Specify whether to use server-side IPv6 addresses

The HTTPDNS service supports access from both IPv4 and IPv6 addresses. You can use the DNSResolver.setEnableIPv6(boolean enable) method to specify whether to use server-side IPv6 addresses. If you set this parameter to true, the SDK uses IPv6 addresses to access the server. If you set it to false or do not set it, the SDK uses IPv4 addresses by default. If you enable IPv6 access and the HTTPDNS service cannot be reached, the SDK automatically switches to IPv4 and retries the request one time.

5. Set the maximum number of cached entries

DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); // Set the maximum number of cached entries. Default value: 100.

You can customize the maximum value.

6. Set the server access protocol

The SDK lets you set the protocol for DNS resolution requests to either HTTP or HTTPS. The SDK uses and recommends the HTTPS protocol for resolution because it is more secure. HTTPDNS billing is based on the number of resolution requests, and HTTPS requests are billed at five times the rate of HTTP requests. Select a protocol based on your requirements.

DNSResolver.setSchemaType(DNSResolver.HTTPS); // The default access mode is HTTPS.

DNSResolver.HTTP: Accesses server-side interfaces over HTTP.

DNSResolver.HTTPS: Accesses server-side interfaces over HTTPS.

7. Set the port number for socket-based IP probing

DNSResolver.setSpeedPort(DNSResolver.PORT_80);

You can set the port number for socket-based IP probing. The default port is 80.

Other advanced settings

1. Enable or disable SDK debug logs

DNSResolver.setEnableLogger(true); // SDK debugging logs are disabled by default.

Specifies whether to enable SDK debugging logs. Set the value to true to enable them, or false to disable them.

2. Specify whether to enable automatic fallback to LocalDNS when HTTPDNS resolution fails

DNSResolver.setEnableLocalDns(true); // By default, automatic fallback to LocalDNS resolution is enabled when HTTPDNS resolution fails.

3. Enable or disable Short mode

The DNS over HTTPS (DoH) JSON API for HTTPDNS returns data in either the full JSON format or a concise IP address array format. You can call DNSResolver.setEnableShort(boolean enable) to enable or disable Short mode. By default, Short mode is disabled. For example:

DNSResolver.setEnableShort(true); // The default value is false. You do not need to set this parameter.
Important

In short mode, an SDK call to the HTTPDNS service returns a simplified IP address array. This reduces the amount of response data, making it ideal for scenarios that are sensitive to network traffic.

4. Enable the non-expiring cache

DNSResolver.setImmutableCacheEnable(false); // The non-expiring cache is disabled by default.
Important

The SDK has three internal cache update mechanisms:

  • Non-expiring cache: When this feature is enabled, the cache is considered valid for the entire runtime of the app. Cache expiration checks and updates are no longer performed. You do not need to call setKeepAliveDomains to actively update the cache. This minimizes the number of resolutions.

    Method: DNSResolver.setImmutableCacheEnable(boolean var0)

    Parameter description: If the var0 parameter is true, the non-expiring cache feature is enabled. If var0 is false, the non-expiring cache feature is disabled.

  • Active cache update: This mechanism helps ensure that resolution requests use the latest cached DNS record. When the TTL of a specified domain name drops to 75% of its original value, the SDK automatically triggers a new resolution query to update the cache. This reduces DNS latency for subsequent requests and helps keep the cache up-to-date, especially when the authoritative zone for a domain name changes. We recommend that you limit the number of domain names that are configured for active updates. A maximum of 10 domain names is supported.

    Method: DNSResolver.setKeepAliveDomains(String[] var1)

    Parameter description: var1 is an array of domain name strings that require active updates.

  • Passive cache update:

    When you call the following two methods to retrieve resolution results, the cache is passively updated:

    • getIPsV4ByHost(String hostName) method: Retrieves the IPv4 record array that corresponds to the hostName. If the cache is not empty and the record has not expired, the cached result is returned. Otherwise, the method retrieves the latest resolution result through a network request, returns the result, and then updates the cache. This method is often used in scenarios that require high accuracy for resolution results.

    • getIpv4ByHostFromCache(String hostName, boolean isAllowExp) method: Retrieves the IPv4 record array that corresponds to the hostName from the cache. This method determines whether to return expired resolution results from the cache based on the value of the isAllowExp parameter. We recommend that you use this method in conjunction with the preload method when the app starts. This ensures that the app caches the latest resolution results at startup.

      If isAllowExp is set to true, stale records are returned even if the cache has expired. If the cache is empty, null is returned. If isAllowExp is set to false, null is returned if the cache has expired or is empty. In both cases, an asynchronous request is sent to update the cache.

    Recommended example :

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

5. Configure the cache

DNSResolver.setEnableCache(true); // The cache is enabled by default.

Specifies whether the cache feature is enabled. Set the value to true to enable the cache, or false to disable it.

6. Enable IP speed testing

DNSResolver.setEnableSpeedTest(false); // IP speed testing is disabled by default.

Specifies whether to enable the IP speed testing feature. A value of true enables the feature and a value of false disables it.

7. Configure ISP-based caching for domain names

DNSResolver.setIspEnable(true);// Specifies whether to enable ISP-based domain name caching.

If `setIspEnable` is set to `true`, each network environment (ISP) has its own cache for resolution results. Otherwise, all network environments share a single cache.

8. Set the maximum negative cache TTL

DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE);// Sets the maximum TTL for the negative cache. The default is 30 seconds.

A negative cache stores the response for a domain name that cannot be resolved to an IP address. You can set the maximum TTL for this cache as needed.

9. Set the maximum cache TTL

DNSResolver.setMaxTtlCache(MAX_TTL_CACHE);// Sets the maximum TTL for the cache. The default is 3600 seconds.

You can use the SDK to set a maximum TTL for all cached entries. The default is 3600 s.

10. Configure client subnet information

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

The setEdnsSubnet parameter supports the Extension Mechanisms for DNS (EDNS) Client Subnet (ECS) feature (RFC 7871). This feature sends your subnet information to the authoritative DNS server for more accurate DNS resolution and traffic rerouting. A longer mask provides more precise address information, while a shorter mask provides better user privacy. We recommend a mask length of /24.

Note

In DNS proxy scenarios that use the DNS over HTTPS (DoH) JSON API, the DNS proxy uses this parameter to pass a user's subnet information to HTTPDNS, which then forwards the information to the authoritative server.

For example, when DNSResolver.setEdnsSubnet("1.2.XX.XX/24") is called, the authoritative server uses the 1.2.XX.XX/24 address prefix to provide an optimized resolution result.

11. Setting the domain name resolution timeout

The timeout property specifies the timeout for domain name resolution. The default value is 3 s. You can set a custom value between 2 s and 5 s.

DNSResolver.setTimeout(3);

12. Retrieve the session ID for troubleshooting

The sessionId parameter is generated when an app starts and remains constant throughout its lifecycle. All HTTPDNS resolution requests made during the app's lifecycle include this sessionId. The server records this parameter and generates an index. You can use the sessionId to track the app's lifecycle and troubleshoot related issues.

public static String getSessionId()

13. Logging callbacks

A callback that receives logs generated by the SDK.

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

Anti-obfuscation configuration

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

Service API

  /**
   * Preloads domain name resolution by automatically detecting the current network environment:
   * IPv4-only, IPv6-only, or dual-stack.
   * In a dual-stack environment, this method preloads both IPv4 and IPv6 resolution results.
   * Call this method during SDK initialization at application startup to store resolution
   * results in the cache. This reduces latency for subsequent domain name resolutions.
   *
   * @param domains The domain names to preload.
   */
   public void preLoadDomains(final String[] domains)

    /**
     * Preloads specified IPv4 or IPv6 domain names.
     * Call this method during SDK initialization at application startup to store resolution
     * results in the cache. This reduces latency for subsequent domain name resolutions.
     *
     * @param qType The type of IP address to preload: IPv4 or IPv6.
     * @param domains The domain names to preload.
     */
    public void preLoadDomains(String qType, final String[] domains)
   /**
   * Gets the resolution data for a domain name by automatically detecting the current
   * network environment: IPv4-only, IPv6-only, or dual-stack.
   * If a valid resolution result exists in the cache, the cached result is returned.
   * If the cache is empty or the result has expired, this method sends a synchronous
   * network request to the server to get the recursive resolution result. The result is then
   * returned and stored in the cache.
   *
   * @param host The domain name to resolve.
   * @return An array of optimal IP addresses based on the current network environment.
   */
    public String[] getIpsByHost(String host)

/**
    * Gets the array of IPv4 records for a hostname.
    * If a valid resolution result exists in the cache, the cached result is returned.
    * If the cache is empty or the result has expired, this method sends a synchronous
    * network request to the server to get the recursive resolution result. The result is then
    * returned and stored in the cache.
    *
    * @param hostName The hostname to resolve, for example, www.taobao.com.
    * @return An array of IPv4 addresses for the specified hostname.
    */
  public  String[] getIPsV4ByHost(String hostName) 

   /**
    * Gets the array of IPv6 records for a hostname.
    * @param hostName The hostname to resolve, for example, www.taobao.com.
    * @return An array of IPv6 addresses for the specified hostname.
    */
  public String[] getIPsV6ByHost(String hostName) 

  

  /**
   * Gets an array of resolved IP addresses from the cache by automatically detecting the
   * current network environment: IPv4-only, IPv6-only, or dual-stack.
   * If the cache is empty, this method returns null and starts an asynchronous query.
   * The query result is then stored in the cache.
   * If a cached result exists and returning expired results is allowed, this method
   * returns the expired IP addresses and then asynchronously updates the cache.
   * If returning expired results is not allowed and the cached result is expired,
   * this method returns null and then asynchronously updates the cache.
   *
   * @param host The host to query, for example, www.taobao.com.
   * @param isAllowExp Specifies whether to return expired resolution data.
   * @return An array of resolved IP addresses for the host from the cache.
   */
   public String[] getIpsByHostFromCache(String host, boolean isAllowExp)
   
    /**
     * Gets an array of resolved IPv4 addresses from the cache.
     * If the cache is empty, this method returns null and starts an asynchronous query.
     * The query result is then stored in the cache.
     * If a cached result exists and returning expired results is allowed, this method
     * returns the expired IP addresses and then asynchronously updates the cache.
     * If returning expired results is not allowed and the cached result is expired,
     * this method returns null and then asynchronously updates the cache.
     *
     * @param host The host to query, for example, www.taobao.com.
     * @param isAllowExp Specifies whether to return expired resolution data.
     * @return An array of resolved IPv4 addresses for the host from the cache.
     */
    private String[] getIpv4ByHostFromCache(String host , boolean isAllowExp)

    /**
     * Gets an array of resolved IPv6 addresses from the cache.
     * If the cache is empty, this method returns null and starts an asynchronous query.
     * The query result is then stored in the cache.
     * If a cached result exists and returning expired results is allowed, this method
     * returns the expired IP addresses and then asynchronously updates the cache.
     * If returning expired results is not allowed and the cached result is expired,
     * this method returns null and then asynchronously updates the cache.
     *
     * @param host The host to query, for example, www.taobao.com.
     * @param isAllowExp Specifies whether to return expired resolution data.
     * @return An array of resolved IPv6 addresses for the host from the cache.
     */
    private String[] getIpv6ByHostFromCache(String host , boolean isAllowExp)

  /**
  * Gets an array of DomainInfo objects for the IPv4 records corresponding to a URL.
  * If a valid resolution result exists in the cache, the cached result is returned.
  * If the cache is empty or the result has expired, this method sends a synchronous
  * network request to the server to get the recursive resolution result. The result is then
  * returned and stored in the cache.
  *
  * @param url The URL, for example, http://www.taobao.com.
  * @return An array of DomainInfo objects of the IPv4 type for the target URL.
  */
  public DomainInfo[] getIPsV4DInfoByUrl(String url) 

  Note: The url in the DomainInfo object is the URL with the host already replaced by an IP address. You do not need to manually modify the URL.

  /**
   * Gets an array of DomainInfo objects for the IPv6 records corresponding to a URL.
   * If a valid resolution result exists in the cache, the cached result is returned.
   * If the cache is empty or the result has expired, this method sends a synchronous
   * network request to the server to get the recursive resolution result. The result is then
   * returned and stored in the cache.
   * 
   * @param url The URL, for example, http://m.taobao.com.
   * @return An array of DomainInfo objects of the IPv6 type for the target URL.
   */
   public DomainInfo[] getIPsV6DInfoByUrl(String url) 

  /**
    * Gets a DomainInfo object for the IPv4 records corresponding to a URL.
    * If a valid resolution result exists in the cache, the cached result is returned.
    * If the cache is empty or the result has expired, this method sends a synchronous
    * network request to the server to get the recursive resolution result. The result is then
    * returned and stored in the cache.
    *
    * @param url The URL, for example, http://m.taobao.com.
    * @return A random DomainInfo object from the collection of IPv4-type objects for the target URL.
    */
    public DomainInfo getIPV4DInfoByUrl(String url) 


  /**
    * Gets a DomainInfo object for the IPv6 records corresponding to a URL.
    * If a valid resolution result exists in the cache, the cached result is returned.
    * If the cache is empty or the result has expired, this method sends a synchronous
    * network request to the server to get the recursive resolution result. The result is then
    * returned and stored in the cache.
    *
    * @param url The URL, for example, http://www.taobao.com.
    * @return A random DomainInfo object from the collection of IPv6-type objects for the target URL.
    */
   public DomainInfo getIPV6DInfoByUrl(String url) 

   Description: The returned domainInfo object encapsulates the following properties.

  /**
   * The auto-incrementing ID for the domain name.
    */
    public String id = null;

   /**
    * The ready-to-use URL with the host already replaced by an IP address.
    */
     public String url = null;

    /**
    * The target service name to set in the HTTP request header.
    */
    public String host = "";

   /**
    * The content body of the response.
    */
   public String data = null;

   /**
    * The time when the request started.
    */
   public String startTime = null;

   /**
    * The time when the request ended. This value is null if the request times out.
    */
   public String stopTime = null; 

   /**
   * The status code returned by the server, such as 200, 404, or 500.
   */
   public String code = null;

  /**
    * Gets an IPv4 record for a hostname.
    * If a valid resolution result exists in the cache, the cached result is returned.
    * If the cache is empty or the result has expired, this method sends a synchronous
    * network request to the server to get the recursive resolution result. The result is then
    * returned and stored in the cache.
  
    * @param hostName The hostname to resolve, for example, www.taobao.com.
    * @return A random IPv4 address from the set of addresses for the target hostname.
    *         If speed testing is enabled, this method returns the optimal IPv4 address.
    */
  public String getIPV4ByHost(String hostName) 

   /**
    * Gets an IPv6 record for a hostname.
    * If a valid resolution result exists in the cache, the cached result is returned.
    * If the cache is empty or the result has expired, this method sends a synchronous
    * network request to the server to get the recursive resolution result. The result is then
    * returned and stored in the cache.
  
    * @param hostName The hostname to resolve, for example, www.taobao.com.
    * @return A random IPv6 address from the set of addresses for the target hostname.
    *         If speed testing is enabled, this method returns the optimal IPv6 address.
    */
   public String getIPV6ByHost(String hostName) 
      

    /**
     * Gets success and failure statistics for requests to HTTPDNS.
     *
     * @return A JSON array string that contains the resolution statistics for all domain names.
     */
    public String getRequestReportInfo()
    
     /**
     * Sets the domain names for which the cache is kept alive.
     * The specified domain names are automatically resolved when 75% of their TTL has passed.
     * This ensures that resolution requests for these domain names always hit the cache,
     * which improves the resolution efficiency of the SDK.
     * Do not set too many domain names for this feature. The current limit is 10.
     * This configuration is independent of pre-resolution.
     *
     * @param persistentCacheDomains
     */
    public synchronized static void setKeepAliveDomains(String[] persistentCacheDomains) {
    
     /**
     * Clears the cache for specified domain names. If the `domains` parameter is null,
     * the cache for all domain names is cleared.
     *
     * @param domains An array of domain names whose cache entries to delete.
     */
    public void clearHostCache(String[] domains){

API call examples

URL: The URL to resolve. For example, http://www.taobao.com.

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

1. Obtain optimal IP data for the current network environment

String[] ip = DNSResolver.getInstance().getIpsByHost(hostname); // Get the optimal IP address from domain name resolution for the current network.

2. Preload domain name resolution for the current network environment

DNSResolver.getInstance().preLoadDomains(domains); // Set domain names for pre-resolution. Replace the preloaded domain names with the domain names that you want to resolve using Alibaba Cloud DNS.

3. Retrieve cached domain name resolutions for the current network environment

String[] ip = DNSResolver.getInstance().getIpsByHostFromCache(hostname,true);// Get domain name resolution data from the cache for the current network environment.

4. Obtain an IPv4 address

String IPV4 = DNSResolver.getInstance().getIPV4ByHost(hostname); // Get the IPv4 address from domain name resolution.

5. Obtain an IPv6 address

String IPV6 =  DNSResolver.getInstance().getIPV6ByHost(hostname); // Get the IPv6 address from domain name resolution.

6. Retrieve the resolved IPv4 address from the cache

String[] IPV4 =  DNSResolver.getInstance().getIpv4ByHostFromCache(hostname , true); // Get the resolved IPv4 address from the cache.

7. Retrieve the resolved IPv6 address from the cache

String[] IPV6 =  DNSResolver.getInstance().getIpv6ByHostFromCache(hostname , true); // Get the resolved IPv6 address from the cache.

8. Retrieve the DomainInfo object by URL

DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(url); // Get the replaced URL.

9. Clear the resolution cache for a specific domain name

DNSResolver.getInstance().clearHostCache(hostName); // Clear the cache for a specified domain name. Set hostName to null to clear the cache for all domain names.

10. Retrieve statistics for successful and failed Alibaba Cloud DNS requests

String reportInfo = DNSResolver.getInstance().getRequestReportInfo(); // Get statistics about successful and failed requests.

The following table describes the fields in the JSON array of statistics on domain name resolution:

 [
      {
         "avgRtt":"1",                         // The average time for domain name resolution. Unit: ms.
         "degradeLocalDnsCount": 0,            // The number of times the service was downgraded to LocalDNS.                       
         "domainName":"www.example.com",       // The resolved domain name.
         "hitDnsCacheCount": 1,                // The number of cache hits.
         "httpabnormalCount": 0,               // The number of failed recursive requests.
         "isp": "China Mobile",                // The name of the carrier.
         "localDnsResolveErrCount": 0,         // The number of failed LocalDNS resolutions.
         "maxRtt": 8.0,                        // The maximum time for domain name resolution. Unit: ms.          
         "nonetworkCount": 0,                  // The number of times the network was unavailable.
         "permissionErrCount": 0,              // The number of failed user authentications.
         "queryType": 1,                       // The IP address type. 1 indicates IPv4 and 28 indicates IPv6.
         "recursiveReqCount": 1,               // The number of recursive queries.
         "reqParameterErrCount": 0,            // The number of times the request parameter format was invalid.
         "reqPathErrCount": 0,                 // The number of URL errors.
         "reqServerErrCount": 0,               // The number of DNS server errors.
         "reqTimeoutCount": 0,                 // The number of DNS service timeouts.
         "resolveSuccessCount": 1,             // The number of successful resolutions.
         "timeoutCount": 0,                    // The number of network timeouts.
         "utfNetWorkErroNum": 0                // The number of data reporting timeouts.
      }
         ......
 ]
Important

Statistics for HTTPDNS domain name resolution are available across the following dimensions: network environment, domain name, and request type.

Example

public class MainActivity extends AppCompatActivity {
   private Button button;
   private TextView tvInfo;
   private TextView tvResult;
   private String hostUrl = "http://www.taobao.com"; // Replace this with the hostUrl that you want to resolve.
   private String hostName = "www.taobao.com"; // Replace this with the hostName that you want to resolve.
   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() {
                      // Call the getIPV4ByHost method in the HTTPDNS SDK to get the IP address after the target domain name is resolved.
                      String ip = DNSResolver.getInstance().getIPV4ByHost(hostName);
                      if(ip != null){
                         tvInfo.setText("The IP address of the resolved domain name is: "+ ip);
                      }
                      // Call the getIPV4DInfoByUrl method in the HTTPDNS SDK to get the URL from the domainInfo object after the target domain name is resolved. In this URL, the host in the original URL is replaced with the IP address.
                      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) {
                // Send a network request.
               String requestUrl = dinfo.url;
               HttpURLConnection conn = null;
               try {
                   URL url = new URL(requestUrl);
                   conn = (HttpURLConnection) url.openConnection();
                   // When you use an IP address for access, set the Host field in the HTTP request header to the resolved domain name.
                   conn.setRequestProperty("Host", url.getHost());// Set the Host field in the HTTP request header.
                   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"; // Set the Account ID that you use to integrate with the SDK in the console.
    private String accessKeyId = "Your AccessKey ID"; // Set the AccessKey ID that you use to integrate with the SDK in the console.
    private String accessKeySecret = "Your AccessKey secret"; // Set the AccessKey secret that you use to integrate with the SDK in the console.

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this, accountId, accessKeyId, accessKeySecret); // Set the Account ID, AccessKey ID, and AccessKey secret for SDK integration in the console.
       DNSResolver.setKeepAliveDomains(new String[]{"your-domain-1","your-domain-2",...}); // If you configure keep-alive domains, resolution is automatically initiated when 75% of the TTL has elapsed. This ensures that resolution requests for the configured domain names always hit the cache.
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"your-preload-domain-1","your-preload-domain-2",...}); // Pre-resolve domain names of the IPv4 type. Replace the preloaded domain names with the domain names that you want to resolve using Alibaba Cloud DNS.
    }
}

Notes

  1. After you use HTTPDNS to resolve a domain name to an IP address, use the IP address to send application requests. Set the Host field in the HTTP request header to the original domain name.

  2. To ensure that your services run correctly, if the HTTPDNS SDK returns an empty IP address for a domain name, you must fall back to using the original domain name for the request. The following code provides an example:

    String ip = DNSResolver.getInstance().getIPV4ByHost("domain name");
    if (ip != null) {
    	// Replace the host in the URL with the IP address for interface requests.
    }else {
    	// Use the original domain name request URL for downgrade requests (use the original URL with the domain name for network requests).
    }
  3. A demo program is available to help you quickly get started with the HTTPDNS SDK. Click here to download the demo program.

  4. After you integrate the SDK, verify the integration by checking for traffic in the Traffic Analysis section of the console. If no traffic is generated, ensure that the Account ID, AccessKey ID, and AccessKey Secret parameters are set correctly.