This topic describes how to integrate the HTTPDNS Android SDK. For an overview of the basic principles of HTTPDNS integration, see Client Integration Overview.
Introduction
This section describes how to integrate the HTTPDNS Android SDK.
This guide applies to Android Studio projects that use Gradle for dependency management.
The SDK supports Android 4.4 (API Level 19) or later.
The targetSdkVersion supports up to Android 14 (API 34).
The SDK supports arm64-v8a, armeabi-v7a, x86, and x86_64 architectures.
The SDK is open source. You can modify the source code to meet special requirements. For more information, see httpdns-android-sdk.
Step 1: Add the SDK to your application
You can add the SDK to your application by adding a dependency using Maven or from a local file.
We recommend adding the dependency using Maven because it is simple to configure, less prone to errors, and easy to update.
1. Add dependency using Maven (Recommended)
1.1 Configure the Maven repository
This section describes the recommended configuration methods: the dependencyResolutionManagement method for Gradle 7.0 or later, and the allprojects method for versions earlier than Gradle 7.0.
1.1.1 dependencyResolutionManagement method
In your root-level (project-level) Gradle file (<project>/settings.gradle), add the Maven repository address to the repositories block within dependencyResolutionManagement.
dependencyResolutionManagement {
repositories {
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}1.1.2 allprojects method
In your root-level (project-level) Gradle file (<project>/build.gradle), add the Maven repository address to the allprojects block's repositories block.
allprojects {
repositories {
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}1.2 Add the SDK dependency
In your module (app-level) Gradle file (typically <project>/<app-module>/build.gradle), add the SDK dependency to the dependencies block.
dependencies {
implementation 'com.aliyun.ams:alicloud-android-httpdns:${httpdnsVersion}'
}You can find the httpdnsVersion in the Android SDK release notes.
2. Add dependency from a local file
2.1 Download the SDK
Select and download HTTPDNS from the EMAS SDK List. Then, copy all files from the SDK package to the <project>/<app-module>/libs directory of your application-level module.
2.2 Add the SDK dependency
2.2.1 Configure the local SDK directory
In your module (app-level) Gradle file (usually <project>/<app-module>/build.gradle), add the path to the local SDK directory.
repositories {
flatDir {
dirs 'libs'
}
}2.2.2 Add the SDK dependency
In your module (app-level) Gradle file (usually <project>/<app-module>/build.gradle), add the SDK dependency to the dependencies block.
dependencies {
implementation (name: 'alicloud-android-httpdns-${httpdnsVersion}', ext: 'aar')
implementation (name: 'alicloud-android-logger-${loggerVersion}', ext: 'aar')
implementation (name: 'alicloud-android-crashdefend-${crashDefendVersion}', ext: 'jar')
implementation (name: 'alicloud-android-ipdetector-${ipdetectorVersion}', ext: 'aar')
implementation 'commons-codec:commons-codec:1.15'
}The SDK version numbers in the example dependency must match the version numbers in the filenames of the downloaded artifacts.
If a missing class error is reported during the compilation process, confirm that the
dependenciesblock includesimplementation fileTree(dir: 'libs', include the following: ['*.jar']).
Step 2: Configure and use the SDK
1. Configure HTTPDNS
// Initialize the configuration. Call this method without handling the return value.
InitConfig config = InitConfig.Builder()
/*
(Optional) Specify the HTTPDNS service cluster for the first domain name resolution request after the application is installed. Subsequent requests are routed to the nearest cluster based on the client's network. You must explicitly select a target region. Valid values: Region.SG, Region.HK, Region.US, and Region.DE.
*/
.setRegion(Region.SG)
/*
(Required) Pass the application context. This is used for purposes such as detecting network changes. You can usually pass the ApplicationContext.
*/
.setContext(context)
/*
(Optional) Configure a secret key for signing requests to the server. This prevents requests from being tampered with. This feature is disabled by default. Enable it for better security.
*/
.setSecretKey(secretKey)
/*
(Optional) Configure the transport-layer protocol for communication between the SDK and the server. Enabling HTTPS provides higher link security. Note the billing differences between HTTP and HTTPS. The default protocol is HTTP. Enable HTTPS for better security.
*/
.setEnableHttps(enableHttps)
/*
(Optional) Set the timeout period for domain name resolution. Unit: milliseconds. The maximum value is 5000 ms. The default value is 2000 ms.
*/
.setTimeoutMillis(2 * 1000)
/*
(Optional) Specify whether to enable the local cache. This optimizes the time consumed by domain name resolution after startup and improves the loading speed of the first screen. This feature is disabled by default. We recommend that you enable it and set the cache duration to 1 day.
*/
.setEnableCacheIp(true, 24 * 60 * 60 * 1000)
/*
(Optional) Specify whether to allow the use of expired cache. If you enable this option, the API can immediately return the last expired IP address to reduce blocking and improve request performance. The SDK asynchronously refreshes the latest resolution result in the background. This feature is enabled by default.
*/
.setEnableExpiredIp(true)
/*
(Optional) Enable sniffing and sorting for the IP address list in the resolution result. Set a list of domain names and ports for detection. We recommend that you configure this for latency-sensitive requests.
*/
.setIPRankingList(ipRankingItemJson.toIPRankingList())
/*
(Optional) Configure an interface to customize the cache TTL. This changes the default cache TTL of the authoritative DNS.
*/
.configCacheTtlChanger(ttlChanger)
/*
(Optional) The IP addresses of some domain names are relatively stable. The cache for these domain names does not need to be frequently refreshed when the network changes. You can use this interface to explicitly inform the SDK.
*/
.configHostWithFixedIp(hostListWithFixedIp)
/*
(Optional) Configure filter conditions for domain names that do not use HTTPDNS for resolution. For domain names in the list, HTTPDNS immediately returns null.
*/
.setNotUseHttpDnsFilter(notUseHttpDnsFilter)
.build()
HttpDns.init(accountID, config);// Initialize the configuration. Call this method without handling the return value.
InitConfig config = new InitConfig.Builder()
/*
(Optional) Specify the HTTPDNS service cluster for the first domain name resolution request after the application is installed. Subsequent requests are routed to the nearest cluster based on the client's network. If you do not want the first request to go to the default cluster, explicitly select a target region, such as Region.SG or Region.HK. The default cluster is Chinese mainland for the Alibaba Cloud China Website and Singapore for the Alibaba Cloud International Website.
*/
.setRegion(Region.SG)
/*
(Required) Pass the application context. This is used for purposes such as detecting network changes. You can usually pass the ApplicationContext.
*/
.setContext(context)
/*
(Optional) Configure a secret key for signing requests to the server. This prevents requests from being tampered with. This feature is disabled by default. Enable it for better security.
*/
.setSecretKey(secretKey)
/*
(Optional) Configure the transport-layer protocol for communication between the SDK and the server. Enabling HTTPS provides higher link security. Note the billing differences between HTTP and HTTPS. The default protocol is HTTP. Enable HTTPS for better security.
*/
.setEnableHttps(enableHttps)
/*
(Optional) Set the timeout period for domain name resolution. Unit: milliseconds. The maximum value is 5000 ms. The default value is 2000 ms.
*/
.setTimeoutMillis(2 * 1000)
/*
(Optional) Specify whether to enable the local cache. This optimizes the time consumed by domain name resolution after startup and improves the loading speed of the first screen. This feature is disabled by default. We recommend that you enable it and set the cache duration to 1 day.
*/
.setEnableCacheIp(true, 24 * 60 * 60 * 1000)
/*
(Optional) Specify whether to allow the use of expired cache. If you enable this option, the API can immediately return the last expired IP address to reduce blocking and improve request performance. The SDK asynchronously refreshes the latest resolution result in the background. This feature is enabled by default.
*/
.setEnableExpiredIp(true)
/*
(Optional) Enable sniffing and sorting for the IP address list in the resolution result. Set a list of domain names and ports for detection. We recommend that you configure this for latency-sensitive services.
*/
.setIPRankingList(ipRankingItemJson.toIPRankingList())
/*
(Optional) Configure an interface to customize the cache TTL. This changes the default cache TTL of the authoritative DNS.
*/
.configCacheTtlChanger(ttlChanger)
/*
(Optional) The IP addresses of some domain names are relatively stable. The cache for these domain names does not need to be frequently refreshed when the network changes. You can use this interface to explicitly inform the SDK.
*/
.configHostWithFixedIp(hostListWithFixedIp)
/*
(Optional) Configure filter conditions for domain names that do not use HTTPDNS for resolution. For domain names in the list, HTTPDNS immediately returns null.
*/
.setNotUseHttpDnsFilter(notUseHttpDnsFilter)
.build();
HttpDns.init(accountID, config);You can implement optimistic DNS caching by configuring
setEnableExpiredIp(true)andsetEnableCacheIp(true, 24 * 60 * 60 * 1000). This feature caches domain name resolution results locally and allows the use of expired IP addresses, which enables most DNS resolutions to be completed locally. This is recommended for business domain names whose resolved IP addresses do not change frequently. For more information, see setEnableCacheIp and setEnableExpiredIp.Setting the setEnableHttps parameter to `true` increases your costs. Before you enable this feature, carefully read the Product billing document.
If you have high security requirements for domain name information or SDNS parameters, you can use the setAesSecretKey interface to enable content-layer encryption for resolution requests. However, using AES content encryption increases your costs. Before you enable this feature, carefully read the Product billing document.
If you do not set
setEnableHttpstotrueduring initialization, you must add theandroid:usesCleartextTraffic="true"configuration to theapplicationnode in the application-levelAndroidManifest.xmlfile. Otherwise, domain name resolution requests will fail on later system versions (targetSdkVersion 27 or higher).
For more information about configuration interfaces, see Configuration interfaces.
2. Get the service instance
The HTTPDNS Android SDK provides domain name resolution services through a global service instance. You can obtain the instance as follows.
val httpdns = HttpDns.getService(accountID)HttpDnsService httpdns = HttpDns.getService(accountID);3. Configure domain name pre-resolution
After you initialize HTTPDNS, you can configure pre-resolution for hot spot domain names that you may use later. This allows the SDK to resolve them in advance and reduces the latency of subsequent resolution requests.
val hostList = arrayListOf<String>()
hostList.add("www.aliyun.com")
httpdns.setPreResolveHosts(hostList)ArrayList<String> hostList = new ArrayList<>();
hostList.add("www.aliyun.com");
httpdns.setPreResolveHosts(hostList);Enabling domain name pre-resolution significantly improves the hit rate of the optimistic DNS cache. This allows most resolution requests to be returned directly from the local cache, which reduces latency from real-time resolution.
Pre-resolution increases the number of resolution requests. We recommend that you enable it only for core service domain names or frequently accessed domain names to achieve the best balance between performance and cost.
4. Perform domain name resolution
HTTPDNS provides multiple domain name resolution methods, including synchronous, asynchronous, and synchronous non-blocking resolution. The following example uses the synchronous non-blocking resolution API.
val httpDnsResult = httpdns.getHttpDnsResultForHostSyncNonBlocking("www.aliyun.com", RequestIpType.auto)HTTPDNSResult httpDnsResult = httpdns.getHttpDnsResultForHostSyncNonBlocking("www.aliyun.com", RequestIpType.auto);The getHttpDnsResultForHostSyncNonBlocking interface only queries the cache and returns the resolution result from the cache. If no resolution result is in the cache or the result has expired, the SDK performs domain name resolution in a worker thread. After a successful resolution, the cache is updated for the next call.
Using this interface with pre-resolution (setPreResolveHosts), persistence cache (setEnableCacheIp), and the option to allow expired IP addresses (setEnableExpiredIp) allows most resolution requests to hit the local cache. This achieves a resolution latency of 0 ms.
If your business strongly relies on the results of HTTPDNS resolution, such as when you use custom resolution or experience severe Local DNS hijacking, use getHttpDnsResultForHostSync or getHttpDnsResultForHostAsync.
Select the appropriate domain name resolution interface for your scenario. For more information about the interfaces, see Domain name resolution interfaces and Custom resolution interfaces.
5. Use the domain name resolution result
After a successful resolution in the previous step, you can obtain the domain name resolution result. For more information about the data structure, see HTTPDNSResult.
The following code provides an example of the resolution process for the OkHttp network library:
object : Dns {
@Throws(UnknownHostException::class)
override fun lookup(host: String): List<InetAddress> {
val httpdnsResult: HTTPDNSResult = HttpDns.getService(accountID)
.getHttpDnsResultForHostSyncNonBlocking(host, RequestIpType.auto)
val inetAddresses: MutableList<InetAddress> = ArrayList()
var address: InetAddress
try {
if (httpdnsResult.ips != null) {
// Process IPv4 addresses
for (ipv4 in httpdnsResult.ips) {
address = InetAddress.getByName(ipv4)
inetAddresses.add(address)
}
}
if (httpdnsResult.ipv6s != null) {
// Process IPv6 addresses
for (ipv6 in httpdnsResult.ipv6s) {
address = InetAddress.getByName(ipv6)
inetAddresses.add(address)
}
}
} catch (e: UnknownHostException) {
}
return if (!inetAddresses.isEmpty()) {
inetAddresses
// Important: Configure fallback to Local DNS
} else Dns.SYSTEM.lookup(host)
}
}new Dns() {
@Override
public List<InetAddress> lookup(String host) throws UnknownHostException {
HTTPDNSResult httpdnsResult = HttpDns.getService(accountID).getHttpDnsResultForHostSync(host, RequestIpType.auto);
List<InetAddress> inetAddresses = new ArrayList<>();
InetAddress address;
try {
if (httpdnsResult.getIps() != null) {
// Process IPv4 addresses
for (String ipv4 : httpdnsResult.getIps()) {
address = InetAddress.getByName(ipv4);
inetAddresses.add(address);
}
}
if (httpdnsResult.getIpv6s() != null) {
// Process IPv6 addresses
for (String ipv6 : httpdnsResult.getIpv6s()) {
address = InetAddress.getByName(ipv6);
inetAddresses.add(address);
}
}
} catch (UnknownHostException e) {
}
if (!inetAddresses.isEmpty()) {
return inetAddresses;
}
return Dns.SYSTEM.lookup(host);
}
};For specific network library integration solutions, see:
Best practices for integrating HTTPDNS with OkHttp on Android
Best practices for integrating HTTPDNS with WebView and a local proxy on Android
Best practices for integrating HTTPDNS with Alibaba Cloud OSS SDK on Android
Best practices for integrating HTTPDNS with ExoPlayer on Android
Best practices for integrating HTTPDNS with WebView and OkHttp on Android
Best practices for integrating HTTPDNS with HttpURLConnection on Android
6. Obfuscation configuration
If you have enabled code obfuscation for your project, add the following rules to your configuration file.
-keep class com.alibaba.sdk.android.**{*;}Step 3: Verify the integration
Verification involves two parts: confirming that the SDK successfully obtains the IP address for the domain name, and confirming that the network library uses this IP address to successfully access the business service.
1. Verify that the IP address is obtained
Confirm that the HTTPDNS SDK successfully resolves the IP address of the target domain name. You can use one of the following two methods for verification:
View resolution logs: View the HTTPDNS resolution logs in the EMAS console. If the logs show a list of IP addresses for the target domain name, the resolution is successful.
Print the SDK return result: Print the resolution callback result from the HTTPDNS SDK directly in your code to check if a valid IP address is returned.
# Initiate a synchronous request D sync request host www.aliyun.com with type both extras : null cacheKey null # Cache query result D host www.aliyun.com result in cache is null # Trigger cloud resolution I sync start request for www.aliyun.com both D ip detector type is 3 D ipdetector type is both D start resolve ip request for www.aliyun.com both # Resolution timeout period D the httpDnsConfig timeout is: 2000 D final timeout is: 2000 D wait for request finish # Initiate a resolution request D request url http://xx.xx.xx.xx:80/xxxx/sign_d?host=www.aliyun.com&sdk=android_2.4.0&query=4,6&sid=CaZk1vTyI3hy&s=b4a34694b7215b4cd6a10376b3425a8e&t=1715772172 # Resolution successful D request success {"ipsv6":[],"host":"www.aliyun.com","ips":[],"ttl":60,"origin_ttl":60} # Update cache D save host www.aliyun.com for type v4 ttl is 60 D save host www.aliyun.com for type v6 ttl is 60 D sync resolve time is: 224 # Return resolution result I request host www.aliyun.com for both and return host:www.aliyun.com, ips:[], ipv6s:[], extras:{}, expired:false, fromDB:false after request
2. Verify that the network library is integrated
A successful integration with the network library means that DNS resolution bypasses Local DNS and uses HTTPDNS. You can use one of the following two methods for verification:
Hijacking simulation test: Set the DNS server of your phone's Wi-Fi network to an invalid address. If your business requests can still be initiated, the integration is successful.
Fault injection test: Use the custom resolution feature of EMAS HTTPDNS to resolve the target domain name to an invalid IP address. If the business request fails, the integration is successful.
Notes
Compilation fails after an SDK upgrade
If compilation fails after you upgrade the SDK, the SDK APIs may have been changed. See Android SDK API and use the new replacement interfaces.
You must write fallback code
Fallback code ensures that when HTTPDNS fails to return the expected result, your application falls back to using Local DNS to complete domain name resolution.
Record the IP address and session ID obtained from HTTPDNS
We provide a solution to troubleshoot resolution issues. This solution requires you to record the IP address and sessionId obtained from HTTPDNS in a log. For more information, see Use the Session Tracing Solution to Troubleshoot Resolution Issues.