Integrate the HTTPDNS Android SDK into your application. The Client Integration Overview explains the basic principles.
Before you begin
Ensure your project meets these requirements:
-
Applies to Android Studio projects that use Gradle for dependency management.
-
Android 4.4 (API Level 19) or later.
-
targetSdkVersion up to Android 14 (API 34).
-
Supported architectures: arm64-v8a, armeabi-v7a, x86, x86_64.
The SDK is open source on httpdns-android-sdk.
Step 1: Add the SDK to your application
Add the SDK through Maven or from a local file.
Maven is recommended for easier updates.
1. Add dependency using Maven (Recommended)
1.1 Configure the Maven repository
Use dependencyResolutionManagement for Gradle 7.0+, or allprojects for earlier versions.
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
Download HTTPDNS from the EMAS SDK List and copy all files to the <project>/<app-module>/libs directory.
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'
}
-
Version numbers in the dependency must match those in the downloaded artifact filenames.
-
If compilation reports a missing class error, 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);-
Enable optimistic DNS caching with
setEnableExpiredIp(true)andsetEnableCacheIp(true, 24 * 60 * 60 * 1000). This caches resolution results locally and serves expired IPs, so most resolutions complete without network access. Recommended for domain names whose resolved IP addresses do not change frequently. setEnableCacheIp, setEnableExpiredIp. -
Setting setEnableHttps to `true` increases costs. Review the Product billing document before enabling.
-
To encrypt resolution requests at the content layer, use setAesSecretKey. AES encryption increases costs — review the Product billing document before enabling.
-
If
setEnableHttpsis not set totrue, addandroid:usesCleartextTraffic="true"to theapplicationnode inAndroidManifest.xml. Without this, resolution requests fail on targetSdkVersion 27 or higher.
All options are documented in Configuration interfaces.
2. Get the service instance
Get the HTTPDNS service instance:
val httpdns = HttpDns.getService(accountID)HttpDnsService httpdns = HttpDns.getService(accountID);3. Configure domain name pre-resolution
Pre-resolve frequently used domain names to reduce latency on subsequent 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);-
Pre-resolution improves cache hit rates. Most requests resolve from local cache without network latency.
-
Pre-resolution increases request volume. Enable only for core or frequently accessed domain names.
4. Perform domain name resolution
HTTPDNS supports synchronous, asynchronous, and synchronous non-blocking resolution. This example uses the synchronous non-blocking API:
val httpDnsResult = httpdns.getHttpDnsResultForHostSyncNonBlocking("www.aliyun.com", RequestIpType.auto)HTTPDNSResult httpDnsResult = httpdns.getHttpDnsResultForHostSyncNonBlocking("www.aliyun.com", RequestIpType.auto);-
getHttpDnsResultForHostSyncNonBlocking returns cached results only. If no result exists or it has expired, the SDK resolves in a background thread and updates the cache for subsequent calls.
-
Combined with setPreResolveHosts, setEnableCacheIp, and setEnableExpiredIp, most requests hit local cache for 0 ms resolution latency.
-
If your service requires guaranteed HTTPDNS results (custom resolution or severe Local DNS hijacking), use getHttpDnsResultForHostSync or getHttpDnsResultForHostAsync.
Choose the resolution method that fits your scenario from Domain name resolution interfaces or Custom resolution interfaces.
5. Use the domain name resolution result
Use the resolution result from the previous step. The data structure is defined in HTTPDNSResult.
OkHttp integration example:
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);
}
};Network library integration guides:
-
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 use code obfuscation, add this ProGuard rule:
-keep class com.alibaba.sdk.android.**{*;}
Step 3: Verify the integration
Verify that the SDK resolves IP addresses and that the network library uses them to access your services.
1. Verify that the IP address is obtained
Confirm that HTTPDNS resolves the target domain name:
-
View resolution logs: Check HTTPDNS resolution logs in the EMAS console. If IP addresses appear for the target domain, resolution succeeded.
-
Print the resolution result in your code to confirm valid IP addresses are 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
Verify that DNS resolution bypasses Local DNS and uses HTTPDNS:
-
Hijacking simulation test: Set your phone's Wi-Fi DNS server to an invalid address. If business requests still succeed, the integration works.
-
Fault injection test: Use the custom resolution feature to resolve the target domain to an invalid IP address. If the request fails, the integration works.
Notes
-
Compilation fails after an SDK upgrade
If compilation fails after an upgrade, check Android SDK API for updated interfaces.
-
You must write fallback code
Fallback code ensures your application uses Local DNS when HTTPDNS is unavailable.
-
Record the IP address and session ID obtained from HTTPDNS
Log the IP address and sessionId from HTTPDNS for troubleshooting. Use the Session Tracing Solution to Troubleshoot Resolution Issues.