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.
You can use either of the preceding methods to integrate the SDK into your project.
Initialize the SDK
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.
}
}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);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
The "Didn't find class BasicHttpParams" error is reported on Android 9.0
This SDK introduces the JNI starting from version 2.1.9. You must configure the NDK in the development environment of your app project.
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);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"});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.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.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
setKeepAliveDomainsto actively update the cache. This minimizes the number of resolutions.Method:
DNSResolver.setImmutableCacheEnable(boolean var0)Parameter description: If the
var0parameter istrue, the non-expiring cache feature is enabled. Ifvar0isfalse, 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:
var1is 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 theisAllowExpparameter. 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,nullis returned. IfisAllowExpis set tofalse,nullis 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.
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.
}
......
]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
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.
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). }A demo program is available to help you quickly get started with the HTTPDNS SDK. Click here to download the demo program.
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.