全部產品
Search
文件中心

HTTPDNS:Android端HTTPDNS+阿里雲OSS SDK最佳實務

更新時間:Nov 07, 2025

通過Android SDK接入流程這篇文檔,您已經瞭解了Android SDK匯入、配置、解析IP、應用到網路程式庫和接入驗證的完整流程,本文主要介紹在Android用戶端上使用阿里雲OSS SDK接入HTTPDNS的具體方案。

1. 背景說明

阿里雲Object Storage Service(Object Storage Service)是一款通用的雲端儲存體服務,可讓開發人員在各類應用中便捷地儲存和訪問帳戶圖片、圖片、音視頻等檔案。在Android端,可以通過整合OSS Android SDK來完成。

為了提升檔案傳輸的穩定性和速度,可以將HTTPDNS SDK與OSS Android SDK進行結合,對OSS網域名稱進行解析。這可以有效實現網域名稱防劫持和DNS解析加速,從而最佳化應用訪問OSS的網路體驗。

2. 基於OkHttp接入HTTPDNS SDK

實現OkHttp的自訂DNS介面,接入HTTPDNS,具體參考Android端HTTPDNS+OkHttp最佳實務

class OkHttpDns constructor(context: Context): Dns {
    private var mContext: Context

    init {
        mContext = context
    }
    @Throws(UnknownHostException::class)
    override fun lookup(host: String): List<InetAddress> {
        val httpdnsResult: HTTPDNSResult = HttpDns.getService(accountID)
            .getHttpDnsResultForHostSync(host, RequestIpType.both)
        val inetAddresses: MutableList<InetAddress> = ArrayList()
        var address: InetAddress
        try {
            if (httpdnsResult.ips != null) {
                //處理IPv4地址
                for (ipv4 in httpdnsResult.ips) {
                    address = InetAddress.getByName(ipv4)
                    inetAddresses.add(address)
                }
            }
            if (httpdnsResult.ipv6s != null) {
                //處理IPv6地址
                for (ipv6 in httpdnsResult.ipv6s) {
                    address = InetAddress.getByName(ipv6)
                    inetAddresses.add(address)
                }
            }
        } catch (e: UnknownHostException) {
        }
        return if (!inetAddresses.isEmpty()) {
            inetAddresses
        } else Dns.SYSTEM.lookup(host)
    }
}
public class OkHttpDns implements Dns {
    private Context mContext;
    public OkHttpDns(Context context) {
        mContext = context;
    }
    @Overridepublic List<InetAddress> lookup(String host) throws UnknownHostException {
        HTTPDNSResult httpdnsResult = HttpDns.getService(accountID).getHttpDnsResultForHostSync(host, RequestIpType.both);
        List<InetAddress> inetAddresses = new ArrayList<>();
        InetAddress address;
        try {
            if (httpdnsResult.getIps() != null) {
                //處理IPv4地址for (String ipv4 : httpdnsResult.getIps()) {
                    address = InetAddress.getByName(ipv4);
                    inetAddresses.add(address);
                }
            }

            if (httpdnsResult.getIpv6s() != null) {
                //處理IPv6地址for (String ipv6 : httpdnsResult.getIpv6s()) {
                    address = InetAddress.getByName(ipv6);
                    inetAddresses.add(address);
                }
            }
        } catch (UnknownHostException e) {

        }

        if (!inetAddresses.isEmpty()) {
            return inetAddresses;
        }

        return okhttp3.Dns.SYSTEM.lookup(host);
    }
}

3. 接入OSS SDK並使用HTTPDNS

建立OKHttpClient執行個體,並配置到OSS代替預設DNS服務。OSS SDK的接入和使用,可以參考OSS Android SDK

// 建立OSS用戶端配置
val conf = ClientConfiguration()
conf.connectionTimeout = 15 * 1000 // 連線逾時,預設15秒。
conf.socketTimeout = 15 * 1000 // socket逾時,預設15秒。
conf.maxConcurrentRequest = 5 // 最大並發請求書,預設5個。
conf.maxErrorRetry = 2 // 失敗後最大重試次數,預設2次。

val builder = OkHttpClient.Builder()
    .dns(OkHttpDns(applicationContext))

// 如果設定了自訂的okHttpClient,ClientConfiguration的部分設定將會失效。您需要將其手動設定到builder上。
if (conf != null) {
    val dispatcher = Dispatcher()
    dispatcher.maxRequests = conf.maxConcurrentRequest

    builder.connectTimeout(conf.connectionTimeout.toLong(), TimeUnit.MILLISECONDS)
        .readTimeout(conf.socketTimeout.toLong(), TimeUnit.MILLISECONDS)
        .writeTimeout(conf.socketTimeout.toLong(), TimeUnit.MILLISECONDS)
        .followRedirects(conf.isFollowRedirectsEnable)
        .followSslRedirects(conf.isFollowRedirectsEnable)
        .dispatcher(dispatcher)

    if (conf.proxyHost != null && conf.proxyPort != 0) {
        builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(conf.proxyHost, conf.proxyPort)))
    }
}

// 僅Android OSS SDK 2.9.12或以上版本支援使用conf.setOkHttpClient()方法。
conf.okHttpClient = builder.build()

val oss = OSSClient(applicationContext, endpoint, credentialProvider, conf)
// 建立OSS用戶端配置
ClientConfiguration conf = new ClientConfiguration();
conf.setConnectionTimeout(15 * 1000); // 連線逾時,預設15秒。
conf.setSocketTimeout(15 * 1000); // socket逾時,預設15秒。
conf.setMaxConcurrentRequest(5); // 最大並發請求書,預設5個。
conf.setMaxErrorRetry(2); // 失敗後最大重試次數,預設2次。

OkHttpClient.Builder builder = new OkHttpClient.Builder()
        .dns(new OkHttpDns(getApplicationContext()));
        
// 如果設定了自訂的okHttpClient,ClientConfiguration的部分設定將會失效。您需要將其手動設定到builder上。
if (conf != null) {
    Dispatcher dispatcher = new Dispatcher();
    dispatcher.setMaxRequests(conf.getMaxConcurrentRequest());

    builder.connectTimeout(conf.getConnectionTimeout(), TimeUnit.MILLISECONDS)
            .readTimeout(conf.getSocketTimeout(), TimeUnit.MILLISECONDS)
            .writeTimeout(conf.getSocketTimeout(), TimeUnit.MILLISECONDS)
            .followRedirects(conf.isFollowRedirectsEnable())
            .followSslRedirects(conf.isFollowRedirectsEnable())
            .dispatcher(dispatcher);

    if (conf.getProxyHost() != null && conf.getProxyPort() != 0) {
        builder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(conf.getProxyHost(), conf.getProxyPort())));
    }
}

// 僅Android OSS SDK 2.9.12或以上版本支援使用conf.setOkHttpClient()方法。
conf.setOkHttpClient(builder.build());

OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider, conf);
重要

HTTPDNS SDK初始化設定需要在OSS SDK初始化設定之前完成。

4. 總結

通過將HTTPDNS與OSS SDK結合,可以有效防止DNS劫持並加速檔案傳輸,提升訪問的穩定性和安全性。

實現的核心是為OSS配置一個帶有HTTPDNS解析邏輯的自訂OkHttpClient

關鍵注意點:

  • 自訂OkHttpClient後,必須將ClientConfiguration中的逾時、並發數等配置手動設定到OkHttpClient.Builder上,否則原配置會失效。

  • 請確保OSS SDK版本不低於2.9.12,並先初始化HTTPDNS,再初始化OSS。