全部產品
Search
文件中心

Alibaba Cloud DNS:Android SDK開發指南

更新時間:Dec 02, 2025

本文檔為您介紹移動解析HTTPDNS Android SDK的整合方式。

概述

Android SDK是基於移動解析HTTPDNSDoH JSON API的封裝,提供Java函數介面給Android APP進行網域名稱解析,並且提供了基於TTL和LRU策略的高效網域名稱緩衝功能。開發人員可以在自己的Android APP中輕鬆接入移動解析HTTPDNS,解決網域名稱解析異常的問題,低成本實現網域名稱解析精準調度。

SDK有如下優勢:

  • 簡單易用

    使用者僅需整合我們提供的SDK,便可接入移動解析HTTPDNS業務。接入方法簡單易用,為使用者提供更為輕鬆便捷的解析服務。

  • 零延遲

    SDK內部實現了LRU的緩衝機制,將每次網域名稱解析後的IP緩衝到本地;並且主動更新TTL到期緩衝,保證緩衝及時有效,從而協助使用者達到網域名稱解析零延遲的效果。

您可以參考alidns_android_demo樣本工程源碼瞭解如何使用本SDK。

SDK整合

引入SDK

通過gradle整合Maven方式整合SDK

在 build.gradle 檔案中加入以下代碼:

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

加入您要引用的檔案資訊:

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

通過aar方式整合SDK

參考SDK下載擷取到的SDK的alidns_android_sdk.aar,將aar包整合到自己工程專案libs目錄中即可便於使用。

說明

您可以通過以上兩種方式任選其一將SDK整合到自己的工程專案裡。

SDK初始化

重要

為了使用者更好地使用SDK,避免出現解析不到IP地址的情況,請將SDK初始化的時間盡量提前。

您需先在控制台唯一標識 Account ID ,並建立密鑰,擷取AccessKey IDAccessKey Secret ,整合SDK後並進行初始化,具體SDK初始化可參考在Application中的程式碼範例。

public class DnsCacheApplication extends Application{

    private String Account ID = "你的Account ID"; //設定您在控制台接入SDK的Account ID
    private String AccessKey ID = "你的AccessKey ID"; //設定您在控制台接入SDK的AccessKey ID
    private String AccessKey Secret = "你的AccessKey Secret "; //設定您在控制台接入SDK的AccessKey Secret

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret); //設定控制台接入SDK的Account ID  AccessKey ID  AccessKey Secret
       //注意:設定緩衝保持配置的網域名稱會在TTL * 75%時自動發起解析,實現佈建網域名解析時始終能命中緩衝,但是如果使用者使用了CDN會導致TTL值很小,從而產生大量的解析請求造成費用上升,請使用者謹慎使用該方法。
       DNSResolver.setKeepAliveDomains(new String[]{"您要緩衝保持的網域名稱1","您要緩衝保持的網域名稱2",...});       
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"您要預先載入的網域名稱1","您要預先載入的網域名稱2",...}); //設定指定IPV4類型網域名稱預解析,將預先載入網域名稱替換為您希望使用阿里DNS解析的網域名稱
    }
}
說明

DNSResolver為移動解析HTTPDNS SDK的核心類,其內部封裝了移動解析HTTPDNS提供的DoH JSON API,將使用者的目標網域名稱解析成對應的IP。接入移動解析HTTPDNS SDK時建議在Application子類裡整合。

另外,Android工程在使用SDK時,需要保證提供以下存取權限的配置:

<!--需要配置的許可權-->
   <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鑒權

本SDK從2.0開始支援設定鑒權認證功能,來保障使用者身份安全,不被第三方未授權者盜用。鑒權功能開啟,請參考建立密鑰在控制台上建立 AccessKey ID AccessKey Secret如果使用者在接入SDK初始化時不設定鑒權參數,則後期移動解析HTTPDNS會拒絕沒有開啟鑒權功能的網域名稱解析請求, 會造成網域名稱解析功能失效影響到使用者實際的業務,因此您在接入移動解析HTTPDNS SDK初始化時務必要設定鑒權參數。

鑒權參數可以通過以下方式進行設定:

DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret);
警告
  • 為避免在日誌中泄漏參數Account ID/AccessKey ID/AccessKey Secret或App運行過程中產生的資料,建議線上版本關閉SDK調試日誌。

  • 由於所有使用者使用統一的SDK接入,在接入過程中需要在代碼中設定Account ID/AccessKey ID/AccessKey Secret參數,而此類參數與計量計費密切相關,為防止惡意反編譯擷取參數造成資訊洩漏,建議您開啟混淆,並進行App加固後再發布上線。

SDK接入常見問題

Android 9.0 發送HTTP網路請求會報cleartext HTTP traffic no permitted異常

原因:從Android9.0(API 28)開始,Android預設禁止明文訪問網路只允許使用https url訪問。

解決方案

在應用的AndroidManifest.xml檔案的<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">

Android9.0會報異常:Didn't find class BasicHttpParams

原因:Apache Http用戶端棄用 。

因為早在Android 6.0中,Google取消了對Apache Http用戶端的支援。從Android 9.0開始,org.apache.http.legacy從bootclasspath中刪除。

該修改對於大多數 taskVersion < 9.0的應用沒有影響,對所有taskVersion > 9.0的應用,如果繼續使用Apache Http介面或者引用的lib包中用到該介面時,都會出現Apache Http介面找不到的異常。

解決方案

在應用的AndroidManifest.xml檔案的<application>中添加:

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

本SDK從2.1.9版本開始引入了JNI,需要在您的App工程專案的開發環境中配置NDK

  • 在App工程專案的根目錄裡local.properties檔案中添加NDK的安裝目錄

ndk.dir=...\\ndk\\21.4.7075529   ...是開發人員本地安裝NDK的路徑
  • 在App工程專案的根目錄裡gradle.properties檔案中添加以下配置

android.useDeprecatedNdk = true

如果您的App工程專案已經有配置NDK,可以忽略無需再配置了。為了更好的使用本SDK,建議您在編譯APP時將JDK的版本設定為1.8,NDK的版本設定為21.4.7075529。

API介紹

常用設定

1、Init方法初始化

在您Application中初始化SDK時調用Init方法。

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

2、設定預解析網域名稱

在您初始化程式時,強烈推薦預先向移動解析HTTPDNS SDK中註冊您後續可能會使用到的網域名稱,以便SDK提前解析,減少後續解析網域名稱時請求的時延。調用以下方法設定預解析網域名稱:

  • 指定預先載入IPV6或IPV4網域名稱解析

//設定指定網域名稱類型預先解析,將預先載入網域名稱替換為您希望使用阿里DNS解析的網域名稱
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{...})

DNSResolver.QTYPE_IPV4  預取網域名稱解析的IPV4記錄類型
DNSResolver.QTYPE_IPV6  預取網域名稱解析的IPV6記錄類型
  • 根據當前網路自動匹配預先載入IPV6或IPV4網域名稱解析,在雙棧網路環境下預先載入IPV6和IPV4類型的網域名稱解析

DNSResolver.getInstance().preLoadDomains(domains)
重要

預解析介面設定的同時會即時觸發非同步網路請求,應該在代碼邏輯上確保調用預解析介面時,已經進行了必要的初始化設定。

3、設定網域名稱緩衝保持

SDK支援設定緩衝保持配置的網域名稱會在TTL * 75%時自動發起解析,實現配置的網域名稱在解析時始終能命中緩衝提升了SDK的解析效率。此項建議不要設定太多網域名稱,當前限制為最多 10 個網域名稱與預解析分開獨立配置。

DNSResolver.setKeepAliveDomains(new String[]{"使用者指定網域名稱1", "使用者指定網域名稱2"});
說明

優勢

1. 可及時(ttl到期前)更新記錄

2. 配合預先載入可降低首次解析延遲(0毫秒)

劣勢

1. 根據ttl *75% 作為重新請求的時機,會帶來額外的費用

4、設定是否使用服務端IPV6地址

移動解析HTTPDNS服務支援IPv4、IPv6雙棧地址訪問,通過DNSResolver.setEnableIPv6(boolean enable)方法來設定是否使用服務端IPv6地址。當設定為true表示使用IPv6的IP地址訪問服務端介面,false表示使用IPv4的IP地址訪問服務端介面。如不顯式設定,預設為使用IPv4地址訪問。另外當設定為IPv6地址時,如果訪問移動解析HTTPDNS服務不通,則自動切換為IPv4地址,並且支援重試1次策略。

5、設定緩衝的最大個數

DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); //設定緩衝的最大個數,預設為100

使用者可以自訂最大count的值。

6、設定訪問服務端協議

SDK支援設定DNS解析HTTP請求協議類型,可自主選擇通過HTTP或HTTPS協議解析。SDK預設並推薦使用HTTPS協議進行解析,因為HTTPS協議安全性更好。移動解析HTTPDNS的計費項目是按HTTP的解析次數進行收費,其中HTTPS是按5倍HTTP流量進行計費,開發人員可以根據自身實際業務需要選擇HTTP請求協議類型

DNSResolver.setSchemaType(DNSResolver.HTTPS); 預設訪問為https的模式。

DNSResolver.HTTP,以HTTP協議訪問服務端介面

DNSResolver.HTTPS,以HTTPS協議訪問服務端介面

7、設定IP測速socket監測的連接埠號碼

DNSResolver.setSpeedPort(DNSResolver.PORT_80)

使用者可以設定IP測速基於socket監測的連接埠號碼,預設為80

其它進階設定

1、設定是否開啟SDK調試日誌開關

DNSResolver.setEnableLogger(true); //預設關閉SDK調試日誌

使用者可以設定是否開啟SDK調試日誌開關(true為開啟調試日誌,false為關閉調試日誌)

2、設定是否開啟使用移動解析HTTPDNS解析失敗時自動降級到localdns進行兜底解析

DNSResolver.setEnableLocalDns(true); //預設開啟使用移動解析HTTPDNS解析失敗時自動降級到localdns兜底解析

3、設定是否開啟Short模式

移動解析HTTPDNS的DoH JSON API返回資料類型分為全量JSON和簡要IP數組格式,可以通過調用DNSResolver.setEnableShort (boolean enable)來開啟或關閉short模式。如不顯式設定,預設為關閉short模式。如下方式:

DNSResolver.setEnableShort (true); //預設值是false,該參數使用者可以不需設定,不設定則預設為false。
重要

short模式為SDK調用移動解析HTTPDNS服務返回的比較簡單的IP數組,可以減少響應的資料量,適用於對網路流量敏感的情境。

4、設定是否開啟緩衝永不到期

DNSResolver.setImmutableCacheEnable(false); //預設不開啟緩衝永不到期
重要

SDK內部共有三種緩衝更新機制:

  • 緩衝永不到期:一旦啟用此功能,那麼在app啟動運行過程中,將始終視緩衝為有效狀態,不再執行緩衝到期檢查和更新操作,使用者不需要設定setKeepAliveDomains來主動更新緩衝,可以最大程度降低使用者解析次數。

    設定方法:DNSResolver.setImmutableCacheEnable(boolean var0)

    參數說明:當參數var0true時,啟用緩衝永不到期功能;當var0false時,關閉緩衝永不到期功能。

  • 主動更新緩衝:主動更新是為了確保解析命中最新解析記錄值緩衝,當網域名稱的權威解析出現變更時,使用本機制既可以保證解析請求命中緩衝,從而降低DNS時延,又可以確保擷取的解析記錄緩衝通常都是最新的記錄值。當設定的網域名稱的TTL值達到75%時,SDK自動觸發解析查詢並更新緩衝。建議控制主動更新的網域名稱數量,最大支援10個。

    設定方法:DNSResolver.setKeepAliveDomains(String[] var1)

    參數說明:var1是需要主動更新的網域名稱字串數組。

  • 被動更新緩衝

    調用下面兩個擷取解析結果方法時,會被動更新緩衝:

    • getIPsV4ByHost(String hostName)方法:擷取hostName對應的IPv4記錄數組。如果緩衝非空且在TTL有效期間內,會直接返回緩衝結果,否則,將先通過網路請求擷取最新解析結果,然後再返回該結果並更新緩衝,該方法多用於對解析結果有較高準確性要求的情境。

    • getIpv4ByHostFromCache(String hostName, boolean isAllowExp)方法:從緩衝中擷取hostName對應的IPv4記錄數組。此方法會根據isAllowExp參數值的不同,決定是否返回緩衝中已到期的解析結果。該方法建議在app啟動時配合preload預先載入方法使用,保證app啟動時就會緩衝最新的解析結果。

      參數說明:若isAllowExptrue,即使緩衝到期也返回舊記錄(緩衝為空白時返回null),並通過非同步請求更新緩衝;若為false,當緩衝已到期或者為空白時,返回null,並通過非同步請求更新緩衝。

    推薦樣本

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

5、設定是否開啟使用緩衝

DNSResolver.setEnableCache(true); //預設開啟使用緩衝

使用者可以設定是否開啟使用緩衝功能(true為開啟緩衝功能,false為關閉緩衝功能)

6、設定是否開啟IP測速

DNSResolver.setEnableSpeedTest(false); //預設不開啟IP測速

使用者可以設定是否開啟IP測速(true為開啟IP測速功能,false為關閉IP測速功能)

7、設定是否開啟依據ISP網路區分網域名稱緩衝

DNSResolver.setIspEnable(true);//是否開啟依據ISP網路區分網域名稱緩衝

設定是否開啟依據ISP網路區分網域名稱緩衝。如果開啟,則在不同網路環境下網域名稱快取資料分別儲存互不影響。如果不開啟,則不同網路下使用同一份網域名稱快取資料

8、設定否定緩衝的最大TTL時間

DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE);//設定否定緩衝的最大TTL時間,預設為30秒

使用者可以根據自身的需求設定否定緩衝(網域名稱沒有配置對應的IP地址,導致解析結果沒有IP返回的無效緩衝)的最大TTL時間。

9、設定緩衝的最大TTL時間

DNSResolver.setMaxTtlCache(MAX_TTL_CACHE);//設定緩衝的最大TTL時間,預設為3600秒

SDK可設定緩衝的最大TTL時間,如果設定了該時間,則會限制緩衝的最大TTL不超過該設定時間。SDK預設該參數為3600s。

10、設定用戶端子網資訊

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

setEdnsSubnet是為了支援DNS ECS功能(RFC7871),將使用者的子網資訊傳遞給權威DNS,以便進行更精確的DNS解析和流量調度。其中,掩碼越長的地址資訊越精確,掩碼越短則使用者隱私效果越好,建議使用“/24”掩碼長度。

說明

該參數是特地為DNS代理(proxy)使用DoH JSON API情境設計,即使用者發送DNS查詢給DNS代理,DNS代理通過該參數攜帶使用者的子網資訊傳遞給移動解析HTTPDNS,最後傳遞到權威DNS伺服器。

例如DNSResolver.setEdnsSubnet("1.2.XX.XX/24"),權威伺服器會收到基於1.2.XX.XX/24地址首碼資訊來協助使用者選擇DNS鏈路。

11、設定網域名稱解析的逾時時間

timeout屬性為網域名稱解析的逾時時間。預設逾時時間為3s,使用者可自訂逾時時間,建議設定在2~5s之間。

DNSResolver.setTimeout(3);

12、擷取SessionId,進行問題排查

sessionId參數在App啟動時產生,在整個App生命週期中不會發生變化。在同一個App生命週期中的移動解析HTTPDNS解析請求均會攜帶同一個sessionId,伺服器則會記錄這個參數,並產生索引。使用sessionId對App生命週期進行追蹤,用於App情境的問題排查。

public static String getSessionId()

13、日誌輸出回調

回調SDK輸出的日誌。

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

反混淆配置

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

服務API

  /**
   * 通過自動感知當前網路環境(IPV4-only、IPV6-only、IPV4和IPV6雙棧)預先載入網域名稱解析
   * 雙棧網路環境下同時預先載入IPV4和IPV6類型的網域名稱解析結果。可在應用啟動時對SDK初始化時調用,
   * 對網域名稱的解析結果提前存入緩衝中,加快後續的網域名稱解析時延。
   *
   * @param domains 預先載入解析的網域名稱
   */
   public void preLoadDomains(final String[] domains)

    /**
     * 指定預先載入IPV6或IPV4網域名稱進行預先載入解析 
     * 可在應用啟動時對SDK初始化時調用,對網域名稱的解析結果提前存入緩衝中,加快後續的網域名稱解析時延
     *
     * @param qType 預先載入解析IPV4還是IPV6
     * @param domains 預先載入解析的網域名稱
     */
    public void preLoadDomains(String qType, final String[] domains)
   /**
   * 通過自動感知當前網路環境(IPV4-only、IPV6-only、IPV4和IPV6雙棧)擷取該網域名稱的解析資料
   * 如果緩衝中存在解析結果且緩衝沒到期則將緩衝裡的解析結果返回給使用者
   * 如果緩衝沒有或緩衝到期則先通過同步網路請求向服務端擷取網域名稱的遞迴解析結果返回給使用者,然後在將解析結果存入緩衝中
   *
   * @param host 使用者所要解析的網域名稱
   * @return 返回根據當前網路環境下的最優IP數組
   */
    public String[] getIpsByHost(String host)

/**
    * 擷取hostName對應IPV4記錄數組
    * 如果緩衝中存在解析結果且緩衝沒到期則將緩衝裡的解析結果返回給使用者
    * 如果緩衝沒有或緩衝到期則先通過同步網路請求向服務端擷取網域名稱的遞迴解析結果返回給使用者,然後在將解析結果存入緩衝中
    *
    * @param hostName例如(www.taobao.com)
    * @return 返回目標hostName對應的IPV4地址的數組
    */
  public  String[] getIPsV4ByHost(String hostName) 

   /**
    * 擷取hostName對應IPV6記錄數組
    * @param hostName例如(www.taobao.com)
    * @return 返回目標hostName對應的IPV6地址的數組
    */
  public String[] getIPsV6ByHost(String hostName) 

  

  /**
   * 通過自動感知當前網路環境(IPV4-only、IPV6-only、IPV4和IPV6雙棧)從緩衝中擷取該網域名稱解析後的IP數組
   * 如果緩衝沒有,該方法是先直接返回null,然後同時進行非同步查詢,最後將查詢到的資料存入緩衝中
   * 如果緩衝存在解析結果,如果允許返回緩衝到期解析結果,則先將到期的解析IP返回給使用者,再進行非同步更新緩衝解析結果
   * 如果不允許返回緩衝到期解析結果,當緩衝到期時先直接返回null給使用者,然後再進行非同步更新緩衝解析結果
   *
   * @param host 查詢的host 例如(www.taobao.com)
   * @param isAllowExp 是否允許返回已到期網域名稱的解析資料
   * @return 擷取緩衝中對應host解析後的IP數組
   */
   public String[] getIpsByHostFromCache(String host, boolean isAllowExp)
   
    /**
     * 從緩衝中擷取該網域名稱解析後的IPV4記錄類型的IP數組
     * 如果緩衝沒有,該方法是先直接返回null,然後同時進行非同步查詢,最後將查詢到的資料存入緩衝中
     * 如果緩衝存在解析結果,如果允許返回緩衝到期解析結果,則先將到期的解析IP返回給使用者,再進行非同步更新緩衝解析結果
     * 如果不允許返回緩衝到期解析結果,當緩衝到期時先直接返回null給使用者,然後再進行非同步更新緩衝解析結果
     *
     * @param host 查詢的host 例如(www.taobao.com)
     * @param isAllowExp 是否允許返回已到期網域名稱的解析資料
     * @return 擷取緩衝中對應host解析後的IPV4記錄類型的IP數組
     */
    private String[] getIpv4ByHostFromCache(String host , boolean isAllowExp)

    /**
     * 從緩衝中擷取該網域名稱解析後的IPV6記錄類型的IP數組
     * 如果緩衝沒有,該方法是先直接返回null,然後同時進行非同步查詢,最後將查詢到的資料存入緩衝中
     * 如果緩衝存在解析結果,如果允許返回緩衝到期解析結果,則先將到期的解析IP返回給使用者,再進行非同步更新緩衝解析結果
     * 如果不允許返回緩衝到期解析結果,當緩衝到期時先直接返回null給使用者,然後再進行非同步更新緩衝解析結果
     *
     * @param host 查詢的host 例如(www.taobao.com)
     * @param isAllowExp 是否允許返回已到期網域名稱的解析資料
     * @return 擷取緩衝中對應host解析後的IPV6記錄類型的IP數組
     */
    private String[] getIpv6ByHostFromCache(String host , boolean isAllowExp)

  /**
  * 擷取url對應IPv4記錄的DomainInfo對象數組
  * 如果緩衝中存在解析結果且緩衝沒到期則將緩衝裡的解析結果返回給使用者
  * 如果緩衝沒有或緩衝到期則先通過同步網路請求向服務端擷取網域名稱的遞迴解析結果返回給使用者,然後在將解析結果存入緩衝中
  *
  * @param url例如(http://www.taobao.com)
  * @return目標url對應IPV4類型的DomainInfo對象數組
  */
  public DomainInfo[] getIPsV4DInfoByUrl(String url) 

  注意:DomainInfo對象中的url為替換host為IP拼接後的url,使用者不需再手動url的替換拼接。

  /**
   * 擷取url對應IPv6記錄的DomainInfo對象數組
   * 如果緩衝中存在解析結果且緩衝沒到期則將緩衝裡的解析結果返回給使用者
   * 如果緩衝沒有或緩衝到期則先通過同步網路請求向服務端擷取網域名稱的遞迴解析結果返回給使用者,然後在將解析結果存入緩衝中
   * 
   * @param url 例如(http://m.taobao.com)
   * @return 目標url對應IPV6類型的DomainInfo對象數組
   */
   public DomainInfo[] getIPsV6DInfoByUrl(String url) 

  /**
    * 擷取url對應IPV4記錄的DomainInfo對象
    * 如果緩衝中存在解析結果且緩衝沒到期則將緩衝裡的解析結果返回給使用者
    * 如果緩衝沒有或緩衝到期則先通過同步網路請求向服務端擷取網域名稱的遞迴解析結果返回給使用者,然後在將解析結果存入緩衝中
    *
    * @param url 例如(http://m.taobao.com)
    * @return 目標url對應IPV4類型的DomainInfo對象集合中隨機的一個
    */
    public DomainInfo getIPV4DInfoByUrl(String url) 


  /**
    * 擷取url對應IPV6記錄的DomainInfo對象
    * 如果緩衝中存在解析結果且緩衝沒到期則將緩衝裡的解析結果返回給使用者
    * 如果緩衝沒有或緩衝到期則先通過同步網路請求向服務端擷取網域名稱的遞迴解析結果返回給使用者,然後在將解析結果存入緩衝中
    *
    * @param url 例如(http://www.taobao.com)
    * @return 目標url對應IPV6類型的DomainInfo對象集合中隨機的一個
    */
   public DomainInfo getIPV6DInfoByUrl(String url) 

   說明:返回的domainInfo對象,主要是封裝了如下屬性

  /**
   * id訪問網域名稱自增的id編號
    */
    public String id = null;

   /**
    * 可以直接使用的url 已經替換了host為ip後的url
    */
     public String url = null;

    /**
    * 需要設定到http header裡面的目標服務名稱
    */
    public String host = "";

   /**
    * 返回的內容體
    */
   public String data = null;

   /**
    * 開始請求的時間
    */
   public String startTime = null;

   /**
    * 請求結束的時間,如果請求逾時,該值為null
    */
   public String stopTime = null; 

   /**
   * server返回的狀態值200 \ 404 \ 500等 
   */
   public String code = null;

  /**
    * 擷取hostName對應IPV4記錄
    * 如果緩衝中存在解析結果且緩衝沒到期則將緩衝裡的解析結果返回給使用者
     * 如果緩衝沒有或緩衝到期則先通過同步網路請求向服務端擷取網域名稱的遞迴解析結果返回給使用者,然後在將解析結果存入緩衝中
  
    * @param hostName例如(www.taobao.com)
    * @return 返回目標hostName對應的IPV4地址集合中的一個隨機IPV4地址,當開啟測速返回一個最優IPV4地址
    */
  public String getIPV4ByHost(String hostName) 

   /**
    * 擷取hostName對應IPV6記錄
    * 如果緩衝中存在解析結果且緩衝沒到期則將緩衝裡的解析結果返回給使用者
    * 如果緩衝沒有或緩衝到期則先通過同步網路請求向服務端擷取網域名稱的遞迴解析結果返回給使用者,然後在將解析結果存入緩衝中
  
    * @param hostName例如(www.taobao.com)
    * @return 返回目標hostName對應的IPV6地址集合中的一個隨機IPV6地址,當開啟測速返回一個最優IPV6地址
    */
   public String getIPV6ByHost(String hostName) 
      

    /**
     * 擷取請求移動解析HTTPDNS成功失敗統計資訊
     *
     * @return 所有的網域名稱解析統計資訊Json數組字串
     */
    public String getRequestReportInfo()
    
     /**
     * 設定網域名稱緩衝保持,配置的網域名稱會在TTL * 75%時自動發起解析, 實現配置的網域名稱在解析時始終能命中緩衝提供了SDK的解析效率。
     * 此項建議不要設定太多網域名稱,當前限制為最多 10 個網域名稱,與預解析分開獨立配置
     *
     * @param persistentCacheDomains
     */
    public synchronized static void setKeepAliveDomains(String[] persistentCacheDomains) {
    
     /**
     * 清除指定網域名稱緩衝,hostname為null時清除所有網域名稱緩衝
     *
     * @param domains 指定刪除緩衝裡的網域名稱數組
     */
    public void clearHostCache(String[] domains){

API使用樣本

URL:傳進來的訪問地址,例如:http://www.taobao.com。

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

1、擷取當前網路環境下的最優IP資料

String[] ip = DNSResolver.getInstance().getIpsByHost(hostname); //擷取當前網路下的最優網域名稱解析IP

2、根據當前網路環境預先載入網域名稱解析

DNSResolver.getInstance().preLoadDomains(domains) //設定網域名稱預先解析,將預先載入網域名稱替換為您希望使用阿里DNS解析的網域名稱

3、根據當前網路環境讀取緩衝中的網域名稱解析資料

String[] ip = DNSResolver.getInstance().getIpsByHostFromCache(hostname,true);//擷取當前網路環境緩衝中的網域名稱解析資料

4、獲得IPv4地址

String IPV4 = DNSResolver.getInstance().getIPV4ByHost(hostname); //擷取IPV4的網域名稱解析

5、獲得IPv6地址

String IPV6 =  DNSResolver.getInstance().getIPV6ByHost(hostname) //擷取IPV6的網域名稱解析

6、從緩衝中擷取ipv4解析地址

String[] IPV4 =  DNSResolver.getInstance().getIpv4ByHostFromCache(hostname , true) //擷取緩衝裡IPV4的網域名稱解析

7、從緩衝中擷取ipv6解析地址

String[] IPV6 =  DNSResolver.getInstance().getIpv6ByHostFromCache(hostname , true) //擷取緩衝裡IPV6的網域名稱解析

8、獲得URL對應的DomainInfo對象

DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(url); //擷取替換的URL

9、清除緩衝中指定網域名稱解析結果

DNSResolver.getInstance().clearHostCache(hostName); //清除指定網域名稱緩衝,hostName設為null則清除所有網域名稱緩衝

10、擷取請求阿里DNS成功失敗統計資訊

String reportInfo = DNSResolver.getInstance().getRequestReportInfo();//擷取成功失敗統計資訊

所有的網域名稱解析的統計資訊JSON字串數組中的欄位含義描述如下:

 [
      {
         "avgRtt":"1",                         // 網域名稱平均解析時間,單位:毫秒(ms)
         "degradeLocalDnsCount": 0,            // 降級到LocalDNS的次數                       
         "domainName":"www.example.com",       // 解析的網域名稱
         "hitDnsCacheCount": 1,                // 命中緩衝的次數
         "httpabnormalCount": 0,               // 遞迴請求失敗的次數
         "isp": "中國移動",                    // 電訊廠商名稱
         "localDnsResolveErrCount": 0,         // LocalDNS解析失敗次數
         "maxRtt": 8.0,                        // 網域名稱最大解析時間,單位:毫秒(ms)          
         "nonetworkCount": 0,                  // 無網路次數
         "permissionErrCount": 0,              // 使用者鑒權失敗次數
         "queryType": 1,                       // ip類型,1代表ipv4、28代表ipv6
         "recursiveReqCount": 1,               // 遞迴查詢的次數
         "reqParameterErrCount": 0,            // 請求參數格式錯誤次數
         "reqPathErrCount": 0,                 // URL錯誤次數
         "reqServerErrCount": 0,               // DNS服務端錯誤次數
         "reqTimeoutCount": 0,                 // DNS服務逾時錯誤次數
         "resolveSuccessCount": 1,             // 解析成功次數
         "timeoutCount": 0,                    // 網路逾時錯誤次數
         "utfNetWorkErroNum": 0                // 資料上報逾時錯誤次數
      }
         ......
 ]
重要

請求移動解析HTTPDNS網域名稱解析統計資料是以網路環境+網域名稱+請求類型為統計維度。

樣本

public class MainActivity extends AppCompatActivity {
   private Button button;
   private TextView tvInfo;
   private TextView tvResult;
   private String hostUrl = "http://www.taobao.com"; //請替換為您需要解析hostUrl
   private String hostName = "www.taobao.com"; //請替換為您需要解析hostName
   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() {
                      //調用移動解析HTTPDNSsdk裡的getIPV4ByHost方法獲得目標網域名稱解析後的IP
                      String ip = DNSResolver.getInstance().getIPV4ByHost(hostName);
                      if(ip != null){
                         tvInfo.setText("您解析網域名稱的IP是:"+ ip);
                      }
                      //調用移動解析HTTPDNSsdk裡getIPV4DInfoByUr擷取目標網域名稱解析後的domainInfo對象中的URL,該URL為已替換原來url中host為IP的url
                      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) {
                //發送網路請求
               String requestUrl = dinfo.url;
               HttpURLConnection conn = null;
               try {
                   URL url = new URL(requestUrl);
                   conn = (HttpURLConnection) url.openConnection();
                   //使用IP的方式進行訪問時,需要設定HTTP要求標頭的HOST欄位為原來的網域名稱
                   conn.setRequestProperty("Host", url.getHost());//設定HTTP要求標頭HOST欄位
                   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 = "你的Account ID"; //設定您在控制台接入SDK的Account ID
    private String AccessKey ID = "你的AccessKey ID"; //設定您在控制台接入SDK的AccessKey ID
    private String AccessKey Secret = "你的AccessKey Secret"; //設定您在控制台接入SDK的AccessKey Secret

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret); //設定控制台接入SDK的Account ID  AccessKey ID  AccessKey Secret
       DNSResolver.setKeepAliveDomains(new String[]{"使用者指定網域名稱1","使用者指定網域名稱2",...}); //設定緩衝保持配置的網域名稱會在TTL * 75%時自動發起解析,實現佈建網域名解析時始終能命中緩衝
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"您要預先載入的網域名稱1","您要預先載入的網域名稱2",...}); //設定指定IPV4類型網域名稱預解析,將預先載入網域名稱替換為您希望使用阿里DNS解析的網域名稱
    }
}

注意事項

  1. 通過移動解析HTTPDNS獲得網域名稱的IP地址後,用戶端可以使用這個IP發送業務請求,HTTP要求標頭的Host欄位需改為原來的網域名稱。

  2. 為了保證使用者業務正常,當通過移動解析HTTPDNS SDK擷取到網域名稱解析對應的IP為空白時,需要應用開發人員使用原網域名稱的請求url地址進行降級請求,範例程式碼如下:

    String ip = DNSResolver.getInstance().getIPV4ByHost("網域名稱");
    if (ip != null) {
    	//替換url中的host為ip進行介面請求
    }else {
    	//使用原網域名稱的請求url地址進行降級請求(使用原帶網域名稱的url進行網路請求)
    }
  3. 為協助使用者更快使用移動解析HTTPDNS SDK,我們為開發人員提供了Demo程式,讀者可以下載到本地作為參考,點擊這裡下載Demo程式。

  4. 使用者在SDK接入完成後,為了驗證接入是否成功,需要在控制台“流量分析”中查看是否有流量產生,如果沒有流量產生請檢查Account IDAccessKey ID AccessKey Secret參數是否設定正確。