通過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。