全部产品
Search
文档中心

HTTPDNS:Android SDK接入

更新时间:Aug 14, 2023

本章节介绍了HTTPDNS Android SDK的接入方法。

前提条件

  • 如果要手动集成,需要下载SDK包,最新版本为V2.3.0-intl

样例代码

  • HTTPDNS Android SDK全新Demo工程,请参见HTTPDNS Android Demo,新Demo工程使用Kotlin + MVVM开发,涵盖了SDK各项功能,包含了最佳实践,开发者可通过新Demo更快速了解如何使用HTTPDNS。

  • SDK已开源,如有特殊需求,可以自行更改源码进行使用,请参见httpdns-android-sdk

集成步骤

配置SDK的Maven仓库地址

7.0以下版本

打开项目根目录的build.gradle文件,在allprojectsrepositories中添加Maven仓库地址:

allprojects {
    repositories {
        maven {
            url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
        }
    }
}

7.0以上版本

打开项目根目录的settings.gradle文件,在dependencyResolutionManagementrepositores中添加Maven仓库地址

dependencyResolutionManagement {
  repositories {
    maven {
      url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
      name 'aliyun'
      //一定要添加这个配置
      allowInsecureProtocol = true 
    }
  }

添加SDK依赖

打开应用模块下的build.gradle文件,在dependencies中添加SDK依赖

dependencies {
    compile 'com.aliyun.ams:alicloud-android-httpdns:2.3.0-intl'
}

配置SDK

混淆配置

如果您的项目中使用Proguard等工具做了代码混淆,请保留以下配置:

-keep class com.aliyun.ams.ipdetector.Inet64Util{*;}
-keep class com.alibaba.sdk.android.**{*;}
-keep class com.ut.**{*;}
-keep class com.ta.**{*;}

SDK初始化

获取服务实例

HTTPDNS Android SDK以全局service实例的方式提供域名解析服务,您可以通过以下方式获取实例。

  1. 普通方式

    HttpDnsService httpdns = HttpDns.getService(applicationContext, accountID);
    // 参数applicationContext是您Android App的Context
    // 参数accountID是系统分配的Account ID,当您开通HTTPDNS后,您可以在控制台获取到您对应的Account ID信息
  2. 鉴权方式

    说明
    • HTTPDNS SDK V1.1.3及以上版本支持鉴权方式,该方式需要在HTTPDNS控制台进行关闭非鉴权接口(请谨慎操作)详情请参见鉴权解析接口

    • 鉴权默认过期时间为10分钟。

    • 为避免在日志中泄漏参数accountID/secretKey或App运行过程中产生的数据,建议线上版本关闭SDK调试日志。

    • 由于所有用户使用统一的SDK接入,在接入过程中需要在代码中设accountID/secretKey参数,而此类参数与计量计费密切相关,为防止恶意反编译获取参数造成信息泄漏,建议您开启混淆,并进行App加固后再发布上线。

    HttpDnsService httpdns = HttpDns.getService(applicationContext, accountID, secretKey);
    // 参数applicationContext是您Android App的Context
    // 参数accountID是系统分配的Account ID,当您开通HTTPDNS后,您可以在控制台获取到您对应的Account ID信息
    // 参数secretKey是鉴权对应的secretKey

初始化配置服务(可选,2.2.1版本开始支持)

在获取服务实例之后,我们可以通过初始化配置,设置服务的一些属性,避免服务以默认配置运行。建议进行初始化配置,避免单独调用API产生的时序问题。不进行初始化配置,也不影响基础功能使用。此处是代码示例,参数说明请查看初始化配置

        // 初始化配置,调用即可,不必处理返回值。
        new InitConfig.Builder()
                // 配置初始的region
                .setRegion(currentRegion)
                // 配置是否启用https,默认http
                .setEnableHttps(enableHttps)
                // 配置服务请求的超时时长,毫秒
                .setTimeout(10 * 1000)
                // 配置是否启用本地缓存,默认不启用
                .setEnableCacheIp(true)
                // 配置是否允许返回过期IP,默认允许
                .setEnableExpiredIp(true)
                // 配置ipv4探测域名
                .setIpProbeItems(list)
                // 配置接口来自定义缓存的ttl时间
                .configCacheTtlChanger(ttlChanger)
                // 配置固定IP的域名列表,优化SDK的内部逻辑,减少解析频次
                .configHostWithFixedIp(hostListWithFixedIp)
                // 针对哪一个account配置
                .buildFor(accountID);

设置预解析域名

在您初始化程序时,可以选择性地预先向HTTPDNS SDK中注册您后续可能会使用到的域名,以便SDK提前解析,减少后续解析域名时请求的时延。

您只需调用以下接口:

ArrayList<String> hostList = new ArrayList<>(Arrays.asList("www.taobao.com", "www.aliyun.com"));
httpdns.setPreResolveHosts(hostList);
重要

预解析接口设置的同时会触发异步网络请求,应该在代码逻辑上确保调用预解析接口时,已经进行了必备的初始化设置。比如setHTTPSRequestEnabled: 需要在预解析接口之前调用,否则会导致预解析的相关IP采用HTTP请求。

注意事项

  1. 务必编写降级代码

    降级代码指的是HTTPDNS无法获取期望结果时的处理代码。请参见设置降级策略相关接口

  2. 记录从HTTPDNS获取的IP及sessionId

    我们提供了用于解析问题排查的解决方案,需要您将从HTTPDNS获取的IP及sessionId记录到日志中,详情请参见如何使用“会话追踪方案”排查解析异常

  3. 设置HTTP请求头HOST字段

    标准的HTTP协议中服务端会将HTTP请求头HOST字段的值作为请求的域名信息进行解析。

    使用HTTPDNS后,您可能需要将HTTP请求URL中的HOST字段替换为HTTPDNS解析获得的IP,这时标准的网络库会将您的IP赋值给HTTP请求头的HOST字段,进而导致服务端的解析异常(服务端认可的是您的域名信息,而非IP信息)。

    为了解决这个问题,您可以主动设置HTTP请求HOST字段的值,如:

    String originalUrl = "http://www.aliyun.com/";
    URL url = new URL(originalURL);
    String originalHost = url.getHost();
    // 异步接口获取IP
    String ip = httpdns.getIpByHostAsync(originalHost);
    HttpURLConnection conn;
    if (ip != null) {
        // 通过HTTPDNS获取IP成功,进行URL替换和HOST头设置
        url = new URL(originalUrl.replaceFirst(originalHost, ip));
        conn = (HttpURLConnection) url.openConnection();
        // 设置请求HOST字段
        conn.setRequestProperty("Host", originalHost);
    } else {
        conn = (HttpURLConnection) url.openConnection();
    }
  4. Cookie字段

    部分网络库支持Cookie的自动存储管理,当您使用HTTPDNS进行IP URL请求时,部分网络库会将您URL中的IP信息作为Cookie对应的域名信息进行存储管理(而非HTTP请求头HOST字段信息),进而造成Cookie管理与使用上的困扰,因此您需要关闭Cookie的自动管理功能(默认关闭)。

  5. HTTPS/WebView/SNI场景

    1. HTTPS场景,参考Android端HTTPS(含SNI)业务场景:IP直连方案

    2. WebView场景,参考Android端HTTPDNS+Webview最佳实践

  6. 代理情况下的使用

    当存在中间HTTP代理时,客户端发起的请求中请求行会使用绝对路径的URL,在您开启HTTPDNS并采用IP URL进行访问时,中间代理将识别您的IP信息并将其作为真实访问的HOST信息传递给目标服务器,这时目标服务器将无法处理这类无真实HOST信息的HTTP请求。

    移动网关提供了X-Online-Host的私有协议字段来解决这个问题,比如:

    目标URL:http://www.example.com/product/oss/
    通过HTTPDNS解析出来的www.example.com的IP:192.168.XX.XX
    代理:10.0.XX.XX:XX
    您的HTTP请求头:
    GET http://192.168.XX.XX/product/oss/ HTTP/1.1     # 通过代理发起的HTTP请求头,请求行是一个绝对路径
    Host: www.example.com                         # 这个Header会被代理网关忽略,代理网关会使用请求行绝对路径中的host字段作为源站的host,即192.168.XX.XX
    X-Online-Host: www.example.com                # 这个Header就是移动网关为了传递真实Host添加的私有头部,源站需要配置识别该私有头部以获取真实的Host信息

    同样您可以通过setRequestProperty方法进行X-Online-Host请求头域的设置,并在服务端设置对该私有头域的解析。

    说明

    在绝大多数场景下,我们建议您在代理模式下关闭HTTPDNS功能。