All Products
Search
Document Center

Alibaba Cloud DNS:Android SDK development guide

Last Updated:Aug 14, 2025

This document describes how to integrate and develop with the Alibaba Cloud Public DNS Android SDK.

1. Overview

Alibaba Cloud Public DNS SDK provides DNS resolution services for mobile developers.

With this SDK, developers can easily integrate Alibaba Cloud Public DNS into their Android apps to solve domain name resolution issues and implement precise domain name resolution scheduling at a low cost. You can refer to the demo project source code to learn how to use this SDK.

This SDK encapsulates the DoH JSON API for Alibaba Cloud Public DNS. It provides Java function interfaces for Android apps to resolve domain names and offers efficient domain name caching based on TTL and LRU strategies. In addition to the original features of Public DNS, the SDK also provides the following advantages:

  • Ease of use

    Users only need to integrate the SDK to access Alibaba Cloud Public DNS service. The integration method is simple and easy to use, providing a more convenient resolution service.

  • Zero latency

    The SDK implements an LRU caching mechanism that caches IP addresses of each domain name resolution to the local device. It also actively updates expired cache to ensure the cache is timely and effective, helping users achieve zero latency for domain name resolution.

2. SDK integration

  • You need to register your application in the console first to obtain the unique identifier Account ID

  • Then fill in the AccessKey ID and AccessKey Secret authentication parameters in the AndroidManifest.xml file in your project directory

  • Integrate the SDK into your app project

2.1 Integrate the SDK through Maven using Gradle

Add the following code to the build.gradle file:

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

Add the file information you want to reference:

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

2.2 Integrate the SDK using the AAR method

Refer to SDK download to obtain the SDK's alidns_android_sdk.aar, and integrate the AAR package into your project's libs directory to use it easily.

Note

You can choose either of these two methods to integrate the SDK into your project.

2.3 SDK initialization

Important

For better use of the SDK and to avoid situations where IP addresses cannot be resolved, initialize the SDK as early as possible.

You need to register your application in the console first to obtain the unique identifier Account ID and authentication parameters AccessKey ID and AccessKey Secret. After integrating the SDK, initialize it. For specific SDK initialization, refer to the code example in the Application:

public class DnsCacheApplication extends Application{

    private String Account ID = "your Account ID"; //Set your Account ID for SDK integration in the console
    private String AccessKey ID = "your AccessKey ID"; //Set your AccessKey ID for SDK integration in the console
    private String AccessKey Secret = "your AccessKey Secret "; //Set your AccessKey Secret for SDK integration in the console

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret); //Set the Account ID, AccessKey ID, and AccessKey Secret for SDK integration in the console
       //Note: Setting keep-alive domains will automatically initiate resolution when the TTL reaches 75%, ensuring that domain name resolution always hits the cache. However, if users use CDN, this may result in a very small TTL value, generating many resolution requests and increasing costs. Please use this method with caution.
       DNSResolver.setKeepAliveDomains(new String[]{"Your keep-alive domain 1","Your keep-alive domain 2",...});       
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"Your preload domain 1","Your preload domain 2",...}); //Set specified IPv4 type domain preresolution, replace preload domains with the domains you want to resolve using Alibaba DNS
    }
}
Note

DNSResolver is the core class of Alibaba Cloud Public DNS SDK. It encapsulates the DoH JSON API provided by Alibaba Cloud Public DNS, which resolves the target domain name into the corresponding IP. When accessing Alibaba Cloud Public DNS SDK, we recommend integrating the SDK into the Application class of your Android app.

Additionally, when using the SDK in an Android project, you need to ensure that the following access permissions are configured:

<!--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"/>

2.4 SDK authentication

Starting from version 2.0, this SDK supports authentication to ensure user identity security and prevent unauthorized third-party use. To enable authentication, please refer to Create a key to create AccessKey ID and AccessKey Secret in the console. If users do not set authentication parameters during SDK initialization, Public DNS will reject domain name resolution requests without authentication enabled in the future, which will cause domain name resolution function to fail and affect users' actual business. Therefore, you must set authentication parameters when initializing the Alibaba Cloud Public DNS SDK.

Authentication parameters can be set in the following way:

DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret);
Warning
  • To avoid leaking parameters such as Account ID/AccessKey ID/AccessKey Secret in logs or data generated during app operation, we recommend disabling SDK debugging logs in the online version.

  • Since all users use the same SDK for integration, you need to set Account ID/AccessKey ID/AccessKey Secret parameters in the code during integration. These parameters are closely related to metering and billing. To prevent malicious decompilation from obtaining these parameters and causing information leakage, we recommend enabling obfuscation and reinforcing your app before publishing it online.

3. Common issues with SDK integration

  1. Android 9.0 reports "cleartext HTTP traffic not permitted" exception when sending HTTP network requests

  • Reason: Starting from Android 9.0 (API 28), Android prohibits cleartext network access by default and only allows access to https URLs.

  • Solution

Add the following code to <application> 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">
  1. Android 9.0 reports exception: Didn't find class BasicHttpParams.

  • Reason: 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 with taskVersion < 9.0. For all applications with taskVersion > 9.0, if they continue to use Apache Http interfaces or reference lib packages that use these interfaces, they will encounter exceptions indicating that Apache Http interfaces cannot be found.

  • Solution

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

<uses-library android:name="org.apache.http.legacy" android:required="false"/>
  1. Starting from version 2.1.9, this SDK introduces JNI, which requires NDK configuration in your app project's development environment

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

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

android.useDeprecatedNdk = true

If your app project already has NDK configured, you can ignore this and do not need to configure it again. For better use of this SDK, we recommend setting the JDK version to 1.8 and the NDK version to 21.4.7075529 when compiling your app.

4. API introduction

4.1 Common settings

4.1.1 Init method initialization

Call the Init method when initializing the SDK in your Application.

DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret);

4.1.2 Set pre-resolution domains

When initializing your program, you can optionally pre-register domain names that you may use later with the Alibaba Cloud Public DNS SDK, so that the SDK can resolve them in advance, reducing the request latency for subsequent domain name resolution. Call the following method to set pre-resolution domains:

  • Specify preloading IPv6 or IPv4 domain name resolution

//Set specified domain type pre-resolution, replace preload domains with the domains you want to resolve using Alibaba DNS
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{...})

DNSResolver.QTYPE_IPV4  Preload domain resolution for IPv4 record type
DNSResolver.QTYPE_IPV6  Preload domain resolution for IPv6 record type
  • Automatically match preloading IPv6 or IPv4 domain name resolution based on the current network, preload both IPv6 and IPv4 type domain name resolution in dual-stack network environments

DNSResolver.getInstance().preLoadDomains(domains)
Important

The pre-resolution interface setting will trigger asynchronous network requests in real-time. You should ensure in your code logic that the necessary initialization settings have been made when calling the pre-resolution interface.

4.1.3 Set domain cache keep-alive

The SDK supports setting cache keep-alive for configured domains, which will automatically initiate resolution at 75% of the TTL, ensuring that the configured domains always hit the cache when resolved, improving the resolution efficiency of the SDK. We recommend not setting too many domains for this feature. The current limit is a maximum of 10 domains, configured separately from pre-resolution.

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

Advantages

1. Can update records in a timely manner (before TTL expires)

2. Can reduce first resolution latency (0 milliseconds) when used with preloading

Disadvantages

1. Using 75% of TTL as the time to request again will incur additional costs

4.1.4 Set whether to use server-side IPv6 addresses

Alibaba Cloud Public DNS service supports both IPv4 and IPv6 dual-stack address access. You can use the DNSResolver.setEnableIPv6(boolean enable) method to set whether to use server-side IPv6 addresses. When set to true, it indicates using IPv6 IP addresses to access server-side interfaces. When set to false, it indicates using IPv4 IP addresses to access server-side interfaces. If not explicitly set, it defaults to using IPv4 addresses. Additionally, when set to IPv6 addresses, if access to Alibaba Cloud Public DNS service is not available, it automatically switches to IPv4 addresses and supports a retry policy of 1 time.

4.1.5 Set the maximum number of cache entries

DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); //Set the maximum number of cache entries, default is 100

You can customize the maximum count value.

4.1.6 Set the server access protocol

The SDK supports setting the HTTP request protocol type for DNS resolution, allowing you to choose between HTTP or HTTPS protocols for resolution. The SDK defaults to and recommends using the HTTPS protocol for resolution because the HTTPS protocol is more secure. Public DNS billing is based on the number of HTTP resolution requests, with HTTPS being billed at 5 times the HTTP traffic. Developers can choose the HTTP request protocol type based on their actual business needs.

DNSResolver.setSchemaType(DNSResolver.HTTPS); Default access is in HTTPS mode.

DNSResolver.HTTP, access server-side interfaces using HTTP protocol

DNSResolver.HTTPS, access server-side interfaces using HTTPS protocol

4.1.7 Set the port number for IP speed test socket monitoring

DNSResolver.setSpeedPort(DNSResolver.PORT_80)

Users can set the port number for IP speed test based on socket monitoring, default is 80

4.2 Other advanced settings

4.2.1 Set whether to enable the SDK debug log switch

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

Users can set whether to enable the SDK debug log switch (true to enable debug logs, false to disable debug logs)

4.2.2 Set whether to enable automatic fallback to local DNS for resolution when public DNS resolution fails

DNSResolver.setEnableLocalDns(true); //By default, automatic fallback to local DNS resolution is enabled when Alibaba Cloud Public DNS resolution fails

4.2.3 Set whether to enable Short mode

The DoH JSON API of Alibaba Cloud Public DNS returns data in either full JSON or brief IP array format. You can enable or disable short mode by calling DNSResolver.setEnableShort (boolean enable). If you do not configure DNSResolver.setEnableShort (boolean enable), the short mode is disabled by default. For example:

DNSResolver.setEnableShort (true); //Default value is false, users do not need to set this parameter, if not set, it defaults to false.
Important

Short mode returns a simpler IP array from the SDK's call to Alibaba Cloud Public DNS service, which can reduce the amount of response data and is suitable for scenarios where network traffic is sensitive.

4.2.4 Set whether to enable cache never expires

DNSResolver.setImmutableCacheEnable(false); //Cache never expires is disabled by default
Important

The SDK has three cache update mechanisms internally:

  • Cache never expires: Once this feature is enabled, during the app's runtime, the cache will always be considered valid, and cache expiration checks and updates will no longer be performed. Users do not need to set setKeepAliveDomains to actively update the cache, which can minimize the number of resolutions for users.

    Setting method: DNSResolver.setImmutableCacheEnable(boolean var0)

    Parameter description: When parameter var0 is true, the cache never expires feature is enabled; when var0 is false, the cache never expires feature is disabled.

  • Active cache update: Active update ensures that resolution hits the latest resolution record value in the cache. When the authoritative resolution of a domain name changes, this mechanism can both ensure that resolution requests hit the cache, thereby reducing DNS latency, and ensure that the cached resolution records are usually the latest values. When the TTL value of the set domain reaches 75%, the SDK automatically triggers a resolution query and updates the cache. We recommend controlling the number of domains for active update, with a maximum support of 10.

    Setting method: DNSResolver.setKeepAliveDomains (String[] var1)

    Parameter description: var1 is an array of domain name strings that need to be actively updated.

  • Passive cache update:

    When calling the following two methods to obtain resolution results, the cache is passively updated:

    • getIPsV4ByHost (String hostName) method: Obtain the IPv4 record array corresponding to the hostname. If the cache is not empty and within the TTL validity period, it will directly return the cached result. Otherwise, it will first obtain the latest resolution result through a network request, then return that result and update the cache. This method is often used in scenarios with high accuracy requirements for resolution results.

    • getIpv4ByHostFromCache (String hostName, boolean isAllowExp) method: Obtain the IPv4 record array corresponding to the hostname from the cache. This method will decide whether to return expired resolution results from the cache based on the value of the isAllowExp parameter. This method is recommended to be used with the preload method when the app starts, ensuring that the app caches the latest resolution results at startup.

      Parameter description: If isAllowExp is true, it returns old records even if the cache has expired (returns null if the cache is empty) and updates the cache through an asynchronous request; if it is false, when the cache has expired or is empty, it returns null and updates the cache through an asynchronous request.

    Recommended example:

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

4.2.5 Set whether to enable cache use

DNSResolver.setEnableCache(true); //Cache use is enabled by default

Users can set whether to enable the cache function (true to enable cache function, false to disable cache function)

4.2.6 Set whether to enable IP speed testing

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

Users can set whether to enable IP speed testing (true to enable IP speed testing function, false to disable IP speed testing function)

4.2.7 Set whether to enable domain name cache differentiation based on ISP network

DNSResolver.setIspEnable(true);//Whether to enable domain name cache differentiation based on ISP network

If setIspEnable is set to true, the cached domain name resolution results are separately stored based on the network environments. If setIspEnable is set to false, the same cached domain name resolution results are used in different networks

4.2.8 Set the maximum TTL time for negative cache

DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE);//Set the maximum TTL time for negative cache, default is 30 seconds

Users can set the maximum TTL time for negative cache (invalid cache where the domain name does not have a configured IP address, resulting in no IP being returned in the resolution result) based on their needs.

4.2.9 Set the maximum TTL time for cache

DNSResolver.setMaxTtlCache(MAX_TTL_CACHE);//Set the maximum TTL time for cache, default is 3600 seconds

The SDK can set the maximum TTL time for cache. If this time is set, it will limit the maximum TTL of the cache to not exceed this set time. The default value of this parameter in the SDK is 3600. Unit: seconds.

4.2.10 Set client subnet information

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

setEdnsSubnet is designed to support the DNS ECS feature (RFC7871), which passes the user's subnet information to the authoritative DNS for more accurate DNS resolution and traffic scheduling. The longer the mask, the more precise the address information; the shorter the mask, the better the user privacy effect. We recommend using a mask length of "/24".

Note

This parameter is specifically designed for DNS proxy scenarios using the DoH JSON API, where users send DNS queries to a DNS proxy, and the DNS proxy uses this parameter to carry the user's subnet information to Alibaba Cloud Public DNS, and finally to the authoritative DNS server.

For example, with DNSResolver.setEdnsSubnet("1.2.XX.XX/24"), the authoritative server will receive information based on the 1.2.XX.XX/24 address prefix to help users select the DNS link.

4.2.11 Set the timeout for domain name resolution

The timeout property is the timeout for domain name resolution. The default timeout is 3 seconds. Users can customize the timeout, but we recommend setting it between 2 and 5 seconds.

DNSResolver.setTimeout(3);

4.2.12 Obtain the SessionId for troubleshooting

The `sessionId` parameter is generated when an app starts and remains unchanged throughout its lifecycle. All Public DNS resolution requests made during the same app lifecycle include the same `sessionId`. The server records this parameter and generates an index. You can use the `sessionId` to track the app lifecycle and troubleshoot related issues.

public static String getSessionId()

4.2.13 Log output callback

A callback for logs generated by the SDK.

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

5. Anti-obfuscation configuration

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

6. Service API

  /**
   * Preload domain name resolution by automatically detecting the current network environment (IPv4-only, IPv6-only, IPv4 and IPv6 dual-stack)
   * In dual-stack network environments, preload both IPv4 and IPv6 type domain name resolution results. Can be called during SDK initialization when the application starts,
   * to store domain name resolution results in the cache in advance, speeding up subsequent domain name resolution latency.
   *
   * @param domains Domains to preload for resolution
   */
   public void preLoadDomains(final String[] domains)

    /**
     * Specify preloading IPv6 or IPv4 domains for preload resolution
     * Can be called during SDK initialization when the application starts, to store domain name resolution results in the cache in advance, speeding up subsequent domain name resolution latency
     *
     * @param qType Preload resolution for IPv4 or IPv6
     * @param domains Domains to preload for resolution
     */
    public void preLoadDomains(String qType, final String[] domains)
   /**
   * Obtain the resolution data for this domain by automatically detecting the current network environment (IPv4-only, IPv6-only, IPv4 and IPv6 dual-stack)
   * If the resolution result exists in the cache and the cache has not expired, the resolution result in the cache is returned to the user
   * If there is no cache or the cache has expired, it first obtains the recursive resolution result of the domain name from the server through a synchronous network request and returns it to the user, then stores the resolution result in the cache
   *
   * @param host The domain name that the user wants to resolve
   * @return Returns the optimal IP array based on the current network environment
   */
    public String[] getIpsByHost(String host)

/**
    * Obtain the IPv4 record array corresponding to the hostname
    * If the resolution result exists in the cache and the cache has not expired, the resolution result in the cache is returned to the user
    * If there is no cache or the cache has expired, it first obtains the recursive resolution result of the domain name from the server through a synchronous network request and returns it to the user, then stores the resolution result in the cache
    *
    * @param hostName such as (www.taobao.com)
    * @return Returns the array of IPv4 addresses corresponding to the target hostname
    */
  public  String[] getIPsV4ByHost(String hostName) 

   /**
    * Obtain the IPv6 record array corresponding to the hostname
    * @param hostName such as (www.taobao.com)
    * @return Returns the array of IPv6 addresses corresponding to the target hostname
    */
  public String[] getIPsV6ByHost(String hostName) 

  

  /**
   * Obtain the IP array after resolving the domain name from the cache by automatically detecting the current network environment (IPv4-only, IPv6-only, IPv4 and IPv6 dual-stack)
   * If there is no cache, this method first returns null directly, then performs an asynchronous query, and finally stores the queried data in the cache
   * If the resolution result exists in the cache, if returning expired cache resolution results is allowed, it first returns the expired resolution IP to the user, then asynchronously updates the cache resolution result
   * If returning expired cache resolution results is not allowed, when the cache expires, it first returns null to the user directly, then asynchronously updates the cache resolution result
   *
   * @param host The domain name that you query, such as www.taobao.com.
   * @param isAllowExp Specify whether to return the resolution result of the expired domain name.
   * @return Obtain the IP address array from the cache after the host field is resolved.
   */
   public String[] getIpsByHostFromCache(String host, boolean isAllowExp)
   
    /**
     * Obtain the IP address array of the IPv4 record type from the cache after the host field is resolved.
     * If there is no cache, this method first returns null directly, then performs an asynchronous query, and finally stores the queried data in the cache
     * If the resolution result exists in the cache, if returning expired cache resolution results is allowed, it first returns the expired resolution IP to the user, then asynchronously updates the cache resolution result
     * If returning expired cache resolution results is not allowed, when the cache expires, it first returns null to the user directly, then asynchronously updates the cache resolution result
     *
     * @param host The domain name that you query, such as www.taobao.com.
     * @param isAllowExp Specify whether to return the resolution result of the expired domain name.
     * @return Obtain the IP address array of the IPv4 record type from the cache after the host field is resolved.
     */
    private String[] getIpv4ByHostFromCache(String host , boolean isAllowExp)

    /**
     * Obtain the IP address array of the IPv6 record type from the cache after the host field is resolved.
     * If there is no cache, this method first returns null directly, then performs an asynchronous query, and finally stores the queried data in the cache
     * If the resolution result exists in the cache, if returning expired cache resolution results is allowed, it first returns the expired resolution IP to the user, then asynchronously updates the cache resolution result
     * If returning expired cache resolution results is not allowed, when the cache expires, it first returns null to the user directly, then asynchronously updates the cache resolution result
     *
     * @param host The domain name that you query, such as www.taobao.com.
     * @param isAllowExp Specify whether to return the resolution result of the expired domain name.
     * @return Obtain the IP address array of the IPv6 record type from the cache after the host field is resolved.
     */
    private String[] getIpv6ByHostFromCache(String host , boolean isAllowExp)

  /**
  * Obtain the DomainInfo object array in the IPv4 records that correspond to the URL.
  * If the resolution result exists in the cache and the cache has not expired, the resolution result in the cache is returned to the user
  * If there is no cache or the cache has expired, it first obtains the recursive resolution result of the domain name from the server through a synchronous network request and returns it to the user, then stores the resolution result in the cache
  *
  * @param url such as (http://www.taobao.com)
  * @return Obtain the DomainInfo object array in the IPv4 records that correspond to the URL.
  */
  public DomainInfo[] getIPsV4DInfoByUrl(String url) 

  Note: The URL in the DomainInfo object is the URL in which the host field is automatically replaced by a specific IP address. You do not need to manually replace the host field in the URL.

  /**
   * Obtain the DomainInfo object array in the IPv6 records that correspond to the URL.
   * If the resolution result exists in the cache and the cache has not expired, the resolution result in the cache is returned to the user
   * If there is no cache or the cache has expired, it first obtains the recursive resolution result of the domain name from the server through a synchronous network request and returns it to the user, then stores the resolution result in the cache
   * 
   * @param url such as (http://m.taobao.com)
   * @return Obtain the DomainInfo object array in the IPv6 records that correspond to the URL.
   */
   public DomainInfo[] getIPsV6DInfoByUrl(String url) 

  /**
    * Obtain a DomainInfo object in the IPv4 records that correspond to a specific URL.
    * If the resolution result exists in the cache and the cache has not expired, the resolution result in the cache is returned to the user
    * If there is no cache or the cache has expired, it first obtains the recursive resolution result of the domain name from the server through a synchronous network request and returns it to the user, then stores the resolution result in the cache
    *
    * @param url such as (http://m.taobao.com)
    * @return Obtain a DomainInfo object in the IPv4 records that correspond to the URL.
    */
    public DomainInfo getIPV4DInfoByUrl(String url) 


  /**
    * Obtain a DomainInfo object in the IPv6 records that correspond to a specific URL.
    * If the resolution result exists in the cache and the cache has not expired, the resolution result in the cache is returned to the user
    * If there is no cache or the cache has expired, it first obtains the recursive resolution result of the domain name from the server through a synchronous network request and returns it to the user, then stores the resolution result in the cache
    *
    * @param url such as (http://www.taobao.com)
    * @return Obtain a DomainInfo object in the IPv6 records that correspond to the URL.
    */
   public DomainInfo getIPV6DInfoByUrl(String url) 

   Description: The returned domainInfo object mainly encapsulates the following properties

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

   /**
    * URL that can be used directly, with the host already replaced by IP
    */
     public String url = null;

    /**
    * The service name that needs to be included in the header of the HTTP request.
    */
    public String host = "";

   /**
    * Returned content body
    */
   public String data = null;

   /**
    * Start request time
    */
   public String startTime = null;

   /**
    * Request end time, this value is null if the request times out
    */
   public String stopTime = null; 

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

  /**
    * Obtain the IPv4 record corresponding to the hostname
    * If the resolution result exists in the cache and the cache has not expired, the resolution result in the cache is returned to the user
     * If there is no cache or the cache has expired, it first obtains the recursive resolution result of the domain name from the server through a synchronous network request and returns it to the user, then stores the resolution result in the cache
  
    * @param hostName such as (www.taobao.com)
    * @return A random IPv4 address in the set of IPv4 addresses that correspond to the hostname is returned. If connection speed testing of IP addresses is enabled, the optimal IPv4 address is returned.
    */
  public String getIPV4ByHost(String hostName) 

   /**
    * Obtain the IPv6 record corresponding to the hostname
    * If the resolution result exists in the cache and the cache has not expired, the resolution result in the cache is returned to the user
    * If there is no cache or the cache has expired, it first obtains the recursive resolution result of the domain name from the server through a synchronous network request and returns it to the user, then stores the resolution result in the cache
  
    * @param hostName such as (www.taobao.com)
    * @return Obtain a random IPv6 address in the set of IPv6 addresses that correspond to the hostname. If connection speed testing of IP addresses is enabled, the optimal IPv6 address is returned.
    */
   public String getIPV6ByHost(String hostName) 
      

    /**
     * Obtain the statistics on successful and failed queries of Alibaba Cloud Public DNS.
     *
     * @return Obtain the JSON array string of the resolution statistics on all domain names.
     */
    public String getRequestReportInfo()
    
     /**
     * Set domain cache keep-alive, configured domains will automatically initiate resolution at 75% of TTL, ensuring that configured domains always hit the cache when resolved, improving the resolution efficiency of the SDK.
     * It is recommended not to set too many domains for this feature, the current limit is a maximum of 10 domains, configured separately from pre-resolution
     *
     * @param persistentCacheDomains
     */
    public synchronized static void setKeepAliveDomains(String[] persistentCacheDomains) {
    
     /**
     * Clear the cache of specified domains, clear all domain caches when hostname is null
     *
     * @param domains Array of specified domains to delete from cache
     */
    public void clearHostCache(String[] domains){

7. API usage examples

URL: The access address passed in, for example: http://www.taobao.com.

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

7.1 Obtain the optimal IP data for the current network environment

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

7.2 Preload domain name resolution based on the current network environment

DNSResolver.getInstance().preLoadDomains(domains) //Set domain pre-resolution, replace preload domains with the domains you want to resolve using Alibaba DNS

7.3 Read domain name resolution data from cache based on the current network environment

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

7.4 Obtain IPv4 address

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

7.5 Obtain IPv6 address

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

7.6 Get IPv4 resolution address from cache

String[] IPV4 =  DNSResolver.getInstance().getIpv4ByHostFromCache(hostname , true) //Get IPv4 domain name resolution from cache

7.7 Get IPv6 resolution address from cache

String[] IPV6 =  DNSResolver.getInstance().getIpv6ByHostFromCache(hostname , true) //Get IPv6 domain name resolution from cache

7.8 Obtain the DomainInfo object corresponding to a URL

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

7.9 Clear the resolution result of a specified domain name from the cache

DNSResolver.getInstance().clearHostCache(hostName); //Clear the cache of a specified domain, set hostName to null to clear all domain caches

7.10 Obtain statistics on successful and failed queries of Alibaba DNS

String reportInfo = DNSResolver.getInstance().getRequestReportInfo();//Get success and failure statistics

The field descriptions in the JSON string array of all domain name resolution statistics are as follows:

 [
      {
         "avgRtt":"1",                         // Average domain resolution time, unit: milliseconds (ms)
         "degradeLocalDnsCount": 0,            // Number of times degraded to LocalDNS                       
         "domainName":"www.example.com",       // Resolved domain name
         "hitDnsCacheCount": 1,                // Number of cache hits
         "httpabnormalCount": 0,               // Number of recursive request failures
         "isp": "China Mobile",                // ISP name
         "localDnsResolveErrCount": 0,         // Number of LocalDNS resolution failures
         "maxRtt": 8.0,                        // Maximum domain resolution time, unit: milliseconds (ms)          
         "nonetworkCount": 0,                  // Number of no network occurrences
         "permissionErrCount": 0,              // Number of user authentication failures
         "queryType": 1,                       // IP type, 1 represents IPv4, 28 represents IPv6
         "recursiveReqCount": 1,               // Number of recursive queries
         "reqParameterErrCount": 0,            // Number of request parameter format errors
         "reqPathErrCount": 0,                 // Number of URL errors
         "reqServerErrCount": 0,               // Number of DNS server errors
         "reqTimeoutCount": 0,                 // Number of DNS service timeout errors
         "resolveSuccessCount": 1,             // Number of successful resolutions
         "timeoutCount": 0,                    // Number of network timeout errors
         "utfNetWorkErroNum": 0                // Number of data reporting timeout errors
      }
         ......
 ]
Important

Domain name resolution statistics for Alibaba Cloud Public DNS are based on network environment + domain name + request type as the statistical dimension.

8. Example

public class MainActivity extends AppCompatActivity {
   private Button button;
   private TextView tvInfo;
   private TextView tvResult;
   private String hostUrl = "http://www.taobao.com"; //Please replace with your hostUrl to be resolved
   private String hostName = "www.taobao.com"; //Please replace with your hostName to be resolved
   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 Alibaba Public SDK to obtain the IP after the target domain name is resolved
                      String ip = DNSResolver.getInstance().getIPV4ByHost(hostName);
                      if(ip != null){
                         tvInfo.setText("The IP of your resolved domain is: "+ ip);
                      }
                      //Call the getIPV4DInfoByUr operation in Alibaba Cloud Public SDK to obtain the URL in the domainInfo object after the specified domain name is resolved. The URL is the one in which the host field is replaced by an 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 network request
               String requestUrl = dinfo.url;
               HttpURLConnection conn = null;
               try {
                   URL url = new URL(requestUrl);
                   conn = (HttpURLConnection) url.openConnection();
                   //When an IP address is used for access, you must 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 Account ID = "your Account ID"; //Set your Account ID for SDK integration in the console
    private String AccessKey ID = "your AccessKey ID"; //Set your AccessKey ID for SDK integration in the console
    private String AccessKey Secret = "your AccessKey Secret"; //Set your AccessKey Secret for SDK integration in the console

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret); //Set the Account ID, AccessKey ID, and AccessKey Secret for SDK integration in the console
       DNSResolver.setKeepAliveDomains(new String[]{"User specified domain 1","User specified domain 2",...}); //Setting keep-alive domains will automatically initiate resolution at 75% of TTL, ensuring that domain name resolution always hits the cache
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"Your preload domain 1","Your preload domain 2",...}); //Set specified IPv4 type domain preresolution, replace preload domains with the domains you want to resolve using Alibaba DNS
    }
}

Notes

  1. After you use Alibaba Cloud Public DNS to resolve a domain name to an IP address, you can use the IP address to send business requests. You must specify the host field in the HTTP request header as the domain name that has been resolved.

  2. To ensure normal business operations, when the IP corresponding to the domain name resolution obtained through Alibaba Cloud Public DNS SDK is empty, application developers need to use the original domain name request URL for downgraded requests. Example code is as follows:

    String ip = DNSResolver.getInstance().getIPV4ByHost("domain name");
    if (ip != null) {
    	//Replace the host in the URL with IP for interface requests
    }else {
    	//Use the original domain name request URL for downgraded requests (use the original URL with domain name for network requests)
    }
  3. To help users use Alibaba Cloud Public DNS SDK more quickly, we provide a demo program for developers to download for reference. Click here to download the demo program.

  4. After users complete SDK integration, to verify whether the integration is successful, they need to check if there is traffic generated in the "Traffic Analysis" section of the console. If no traffic is generated, please check whether the Account ID, AccessKey ID and AccessKey Secret parameters are set correctly.