このトピックでは、HTTPDNS Android SDK の統合方法について説明します。HTTPDNS 統合の基本原則の概要については、「クライアント統合の概要」をご参照ください。
はじめに
このセクションでは、HTTPDNS Android SDK の統合方法について説明します。
このガイドは、依存関係の管理に Gradle を使用する Android Studio プロジェクトに適用されます。
SDK は、Android 4.4 (API レベル 19) 以降をサポートしています。
targetSdkVersion は、Android 14 (API 34) までサポートしています。
SDK は、arm64-v8a、armeabi-v7a、x86、および x86_64 アーキテクチャをサポートしています。
SDK はオープンソースです。特別な要件を満たすためにソースコードを修正できます。詳細については、「httpdns-android-sdk」をご参照ください。
ステップ 1: アプリケーションに SDK を追加する
Maven を使用した依存関係の追加、またはローカルファイルからの追加によって、SDK をアプリケーションに追加できます。
設定が簡単で、エラーが発生しにくく、更新も容易なため、Maven を使用して依存関係を追加することを推奨します。
1. Maven を使用した依存関係の追加 (推奨)
1.1 Maven リポジトリを設定する
ここでは、推奨される設定方法について説明します。Gradle 7.0 以降の場合は dependencyResolutionManagement メソッド、Gradle 7.0 より前のバージョンの場合は allprojects メソッドを使用します。
1.1.1 dependencyResolutionManagement メソッド
ルートレベル (プロジェクトレベル) の Gradle ファイル (<project>/settings.gradle) で、dependencyResolutionManagement 内の repositories ブロックに Maven リポジトリのアドレスを追加します。
dependencyResolutionManagement {
repositories {
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}1.1.2 allprojects メソッド
ルートレベル (プロジェクトレベル) の Gradle ファイル (<project>/build.gradle) で、allprojects ブロックの repositories ブロックに Maven リポジトリのアドレスを追加します。
allprojects {
repositories {
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}1.2 SDK 依存関係を追加する
モジュール (アプリレベル) の Gradle ファイル (通常は <project>/<app-module>/build.gradle) で、dependencies ブロックに SDK の依存関係を追加します。
dependencies {
implementation 'com.aliyun.ams:alicloud-android-httpdns:${httpdnsVersion}'
}httpdnsVersion は、「Android SDK リリースノート」で確認できます。
2. ローカルファイルからの依存関係の追加
2.1 SDK をダウンロードする
「EMAS SDK リスト」から HTTPDNS を選択してダウンロードします。次に、SDK パッケージ内のすべてのファイルを、アプリケーションレベルのモジュールの <project>/<app-module>/libs ディレクトリにコピーします。
2.2 SDK 依存関係を追加する
2.2.1 ローカル SDK ディレクトリを設定する
モジュール (アプリレベル) の Gradle ファイル (通常は <project>/<app-module>/build.gradle) で、ローカル SDK ディレクトリへのパスを追加します。
repositories {
flatDir {
dirs 'libs'
}
}2.2.2 SDK 依存関係を追加する
モジュール (アプリレベル) の Gradle ファイル (通常は <project>/<app-module>/build.gradle) で、dependencies ブロックに SDK の依存関係を追加します。
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'
}依存関係の例にある SDK のバージョン番号は、ダウンロードしたアーティファクトのファイル名にあるバージョン番号と一致させる必要があります。
コンパイルプロセス中にクラスが見つからないというエラーが報告された場合は、
dependenciesブロックにimplementation fileTree(dir: 'libs', include the following: ['*.jar'])が含まれていることを確認してください。
ステップ 2: SDK の構成と使用
1. HTTPDNS の構成
// 設定を初期化します。このメソッドを呼び出し、戻り値は処理しません。
InitConfig config = InitConfig.Builder()
/*
(任意) アプリケーションのインストール後、最初のドメイン名解決リクエストに使用する HTTPDNS サービスクラスターを指定します。後続のリクエストは、クライアントのネットワークに基づいて最寄りのクラスターにルーティングされます。ターゲットリージョンを明示的に選択する必要があります。有効な値:Region.SG、Region.HK、Region.US、Region.DE。
*/
.setRegion(Region.SG)
/*
(必須) アプリケーションコンテキストを渡します。これは、ネットワークの変更検出などの目的で使用されます。通常は ApplicationContext を渡すことができます。
*/
.setContext(context)
/*
(任意) サーバーへのリクエストに署名するためのシークレットキーを設定します。これにより、リクエストの改ざんを防ぎます。この機能はデフォルトで無効になっています。セキュリティを向上させるために有効化してください。
*/
.setSecretKey(secretKey)
/*
(任意) SDK とサーバー間の通信に使用するトランスポート層プロトコルを設定します。HTTPS を有効にすると、リンクのセキュリティが向上します。HTTP と HTTPS の課金の違いにご注意ください。デフォルトのプロトコルは HTTP です。セキュリティを向上させるために HTTPS を有効化してください。
*/
.setEnableHttps(enableHttps)
/*
(任意) ドメイン名解決のタイムアウト期間を設定します。単位:ミリ秒。最大値は 5000 ms です。デフォルト値は 2000 ms です。
*/
.setTimeoutMillis(2 * 1000)
/*
(任意) ローカルキャッシュを有効にするかどうかを指定します。これにより、起動後のドメイン名解決にかかる時間が最適化され、最初の画面の読み込み速度が向上します。この機能はデフォルトで無効になっています。有効にして、キャッシュ期間を 1 日に設定することを推奨します。
*/
.setEnableCacheIp(true, 24 * 60 * 60 * 1000)
/*
(任意) 期限切れのキャッシュの使用を許可するかどうかを指定します。このオプションを有効にすると、API は最後に期限切れになった IP アドレスを即座に返し、ブロッキングを減らしてリクエストのパフォーマンスを向上させることができます。SDK はバックグラウンドで最新の解決結果を非同期に更新します。この機能はデフォルトで有効になっています。
*/
.setEnableExpiredIp(true)
/*
(任意) 解決結果の IP アドレスリストのスニッフィングとソートを有効にします。検出用のドメイン名とポートのリストを設定します。遅延の影響を受けやすいリクエストに対して、この設定を推奨します。
*/
.setIPRankingList(ipRankingItemJson.toIPRankingList())
/*
(任意) キャッシュ TTL をカスタマイズするためのインターフェイスを設定します。これにより、権威 DNS のデフォルトのキャッシュ TTL が変更されます。
*/
.configCacheTtlChanger(ttlChanger)
/*
(任意) 一部のドメイン名の IP アドレスは比較的安定しています。これらのドメイン名のキャッシュは、ネットワークが変更されても頻繁に更新する必要はありません。このインターフェイスを使用して、SDK に明示的に通知できます。
*/
.configHostWithFixedIp(hostListWithFixedIp)
/*
(任意) HTTPDNS を使用して解決しないドメイン名のフィルター条件を設定します。リスト内のドメイン名に対して、HTTPDNS は即座に null を返します。
*/
.setNotUseHttpDnsFilter(notUseHttpDnsFilter)
.build()
HttpDns.init(accountID, config);// 設定を初期化します。このメソッドを呼び出し、戻り値は処理しません。
InitConfig config = new InitConfig.Builder()
/*
(任意) アプリケーションのインストール後、最初のドメイン名解決リクエストに使用する HTTPDNS サービスクラスターを指定します。後続のリクエストは、クライアントのネットワークに基づいて最寄りのクラスターにルーティングされます。最初のリクエストをデフォルトのクラスターに送信したくない場合は、Region.SG や Region.HK などのターゲットリージョンを明示的に選択します。デフォルトのクラスターは、Alibaba Cloud 中国サイトでは中国本土、Alibaba Cloud 国際サイトではシンガポールです。
*/
.setRegion(Region.SG)
/*
(必須) アプリケーションコンテキストを渡します。これは、ネットワークの変更検出などの目的で使用されます。通常は ApplicationContext を渡すことができます。
*/
.setContext(context)
/*
(任意) サーバーへのリクエストに署名するためのシークレットキーを設定します。これにより、リクエストの改ざんを防ぎます。この機能はデフォルトで無効になっています。セキュリティを向上させるために有効化してください。
*/
.setSecretKey(secretKey)
/*
(任意) SDK とサーバー間の通信に使用するトランスポート層プロトコルを設定します。HTTPS を有効にすると、リンクのセキュリティが向上します。HTTP と HTTPS の課金の違いにご注意ください。デフォルトのプロトコルは HTTP です。セキュリティを向上させるために HTTPS を有効化してください。
*/
.setEnableHttps(enableHttps)
/*
(任意) ドメイン名解決のタイムアウト期間を設定します。単位:ミリ秒。最大値は 5000 ms です。デフォルト値は 2000 ms です。
*/
.setTimeoutMillis(2 * 1000)
/*
(任意) ローカルキャッシュを有効にするかどうかを指定します。これにより、起動後のドメイン名解決にかかる時間が最適化され、最初の画面の読み込み速度が向上します。この機能はデフォルトで無効になっています。有効にして、キャッシュ期間を 1 日に設定することを推奨します。
*/
.setEnableCacheIp(true, 24 * 60 * 60 * 1000)
/*
(任意) 期限切れのキャッシュの使用を許可するかどうかを指定します。このオプションを有効にすると、API は最後に期限切れになった IP アドレスを即座に返し、ブロッキングを減らしてリクエストのパフォーマンスを向上させることができます。SDK はバックグラウンドで最新の解決結果を非同期に更新します。この機能はデフォルトで有効になっています。
*/
.setEnableExpiredIp(true)
/*
(任意) 解決結果の IP アドレスリストのスニッフィングとソートを有効にします。検出用のドメイン名とポートのリストを設定します。遅延の影響を受けやすいサービスに対して、この設定を推奨します。
*/
.setIPRankingList(ipRankingItemJson.toIPRankingList())
/*
(任意) キャッシュ TTL をカスタマイズするためのインターフェイスを設定します。これにより、権威 DNS のデフォルトのキャッシュ TTL が変更されます。
*/
.configCacheTtlChanger(ttlChanger)
/*
(任意) 一部のドメイン名の IP アドレスは比較的安定しています。これらのドメイン名のキャッシュは、ネットワークが変更されても頻繁に更新する必要はありません。このインターフェイスを使用して、SDK に明示的に通知できます。
*/
.configHostWithFixedIp(hostListWithFixedIp)
/*
(任意) HTTPDNS を使用して解決しないドメイン名のフィルター条件を設定します。リスト内のドメイン名に対して、HTTPDNS は即座に null を返します。
*/
.setNotUseHttpDnsFilter(notUseHttpDnsFilter)
.build();
HttpDns.init(accountID, config);setEnableExpiredIp(true)とsetEnableCacheIp(true, 24 * 60 * 60 * 1000)を設定することで、オプティミスティック DNS キャッシュを実装できます。この機能は、ドメイン名の名前解決結果をローカルにキャッシュし、期限切れの IP アドレスの使用を許可することで、ほとんどの DNS 解決をローカルで完了できるようにします。これは、解決される IP アドレスが頻繁に変更されないビジネスドメイン名に推奨されます。詳細については、「setEnableCacheIp」および「setEnableExpiredIp」をご参照ください。setEnableHttps パラメーターを `true` に設定すると、コストが増加します。この機能を有効にする前に、「製品の課金」ドキュメントをよくお読みください。
ドメイン名情報や SDNS パラメーターに対するセキュリティ要件が高い場合は、setAesSecretKey インターフェイスを使用して、解決リクエストのコンテンツレイヤー暗号化を有効にできます。ただし、AES コンテンツ暗号化を使用するとコストが増加します。この機能を有効にする前に、「製品の課金」ドキュメントをよくお読みください。
初期化時に
setEnableHttpsをtrueに設定しない場合は、アプリケーションレベルのAndroidManifest.xmlファイルのapplicationノードにandroid:usesCleartextTraffic="true"設定を追加する必要があります。そうしないと、後のシステムバージョン (targetSdkVersion 27 以上) でドメイン名の名前解決リクエストが失敗します。
設定インターフェイスの詳細については、「設定インターフェイス」をご参照ください。
2. サービスインスタンスの取得
HTTPDNS Android SDK は、グローバルサービスインスタンスを通じてドメイン名前解決サービスを提供します。インスタンスは次のように取得できます。
val httpdns = HttpDns.getService(accountID)HttpDnsService httpdns = HttpDns.getService(accountID);3. ドメイン名の事前解決の設定
HTTPDNS を初期化した後、後で使用する可能性のあるホットスポットドメイン名の事前解決を設定できます。これにより、SDK が事前にそれらを解決し、後続の解決リクエストの遅延を削減します。
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);ドメイン名の事前解決を有効にすると、オプティミスティック DNS キャッシュのヒット率が大幅に向上します。これにより、ほとんどの解決リクエストがローカルキャッシュから直接返され、リアルタイム解決による遅延が削減されます。
事前解決は解決リクエストの数を増加させます。パフォーマンスとコストの最適なバランスを達成するために、コアサービスドメイン名または頻繁にアクセスされるドメイン名に対してのみ有効にすることを推奨します。
4. ドメイン名解決の実行
HTTPDNS は、同期、非同期、同期非ブロッキング解決など、複数のドメイン名解決メソッドを提供します。次の例では、同期非ブロッキング解決 API を使用します。
val httpDnsResult = httpdns.getHttpDnsResultForHostSyncNonBlocking("www.aliyun.com", RequestIpType.auto)HTTPDNSResult httpDnsResult = httpdns.getHttpDnsResultForHostSyncNonBlocking("www.aliyun.com", RequestIpType.auto);getHttpDnsResultForHostSyncNonBlocking インターフェイスはキャッシュのみをクエリし、キャッシュから解決結果を返します。キャッシュに解決結果がない場合や結果が期限切れの場合、SDK はワーカースレッドでドメイン名の名前解決を実行します。解決が成功すると、次回の呼び出しのためにキャッシュが更新されます。
このインターフェイスを事前解決 (setPreResolveHosts)、永続化キャッシュ (setEnableCacheIp)、および期限切れ IP アドレスを許可するオプション (setEnableExpiredIp) と共に使用すると、ほとんどの解決リクエストがローカルキャッシュにヒットします。これにより、0 ms の解決遅延が実現します。
カスタム解決の使用時や深刻な Local DNS ハイジャックが発生している場合など、ビジネスが HTTPDNS 解決の結果に強く依存している場合は、getHttpDnsResultForHostSync または getHttpDnsResultForHostAsync を使用してください。
シナリオに適したドメイン名解決インターフェイスを選択してください。インターフェイスの詳細については、「ドメイン名解決インターフェイス」および「カスタム解決インターフェイス」をご参照ください。
5. ドメイン名解決結果の使用
前のステップで解決が成功した後、ドメイン名解決結果を取得できます。データ構造の詳細については、「HTTPDNSResult」をご参照ください。
次のコードは、OkHttp ネットワークライブラリの解決プロセスの例を示しています:
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) {
// 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
// 重要: 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) {
// 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 Dns.SYSTEM.lookup(host);
}
};特定のネットワークライブラリ統合ソリューションについては、以下をご参照ください:
6. 難読化の設定
プロジェクトでコードの難読化を有効にしている場合は、設定ファイルに次のルールを追加してください。
-keep class com.alibaba.sdk.android.**{*;}ステップ 3: 統合を検証する
検証には、SDK がドメイン名の IP アドレスを正常に取得したことの確認と、ネットワークライブラリがこの IP アドレスを使用してビジネスサービスに正常にアクセスしたことの確認の 2 つの部分が含まれます。
1. IP アドレスが取得されたことの確認
HTTPDNS SDK がターゲットドメイン名の IP アドレスを正常に解決したことを確認します。検証には、次の 2 つの方法のいずれかを使用できます:
解決ログの表示:EMAS コンソールで HTTPDNS の解決ログを表示します。ログにターゲットドメイン名の IP アドレスのリストが表示されれば、解決は成功です。
SDK の戻り値の出力:コード内で HTTPDNS SDK からの解決コールバック結果を直接出力し、有効な IP アドレスが返されたかどうかを確認します。
# 同期リクエストを開始 D sync request host www.aliyun.com with type both extras : null cacheKey null # キャッシュクエリ結果 D host www.aliyun.com result in cache is null # クラウド解決をトリガー 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 # 解決タイムアウト期間 D the httpDnsConfig timeout is: 2000 D final timeout is: 2000 D wait for request finish # 解決リクエストを開始 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 # 解決成功 D request success {"ipsv6":[],"host":"www.aliyun.com","ips":[],"ttl":60,"origin_ttl":60} # キャッシュを更新 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 # 解決結果を返す I request host www.aliyun.com for both and return host:www.aliyun.com, ips:[], ipv6s:[], extras:{}, expired:false, fromDB:false after request
2. ネットワークライブラリが統合されたことの確認
ネットワークライブラリとの統合が成功すると、DNS 解決は Local DNS をバイパスして HTTPDNS を使用します。検証には、次の 2 つの方法のいずれかを使用できます:
ハイジャックシミュレーションテスト:スマートフォンの Wi-Fi ネットワークの DNS サーバーを無効なアドレスに設定します。ビジネスリクエストがそれでも開始できる場合、統合は成功です。
フォールトインジェクションテスト:EMAS HTTPDNS のカスタム解決機能を使用して、ターゲットドメイン名を無効な IP アドレスに解決します。ビジネスリクエストが失敗した場合、統合は成功です。
注意事項
SDK のアップグレード後にコンパイルが失敗する
SDK をアップグレードした後にコンパイルが失敗する場合、SDK API が変更された可能性があります。「Android SDK API」を参照し、新しい代替インターフェイスを使用してください。
フォールバックコードの記述が必須
フォールバックコードは、HTTPDNS が期待される結果を返せなかった場合に、アプリケーションが Local DNS を使用してドメイン名の名前解決を完了できるようにするためのものです。
HTTPDNS から取得した IP アドレスとセッション ID の記録
解決の問題をトラブルシューティングするためのソリューションを提供しています。このソリューションでは、HTTPDNS から取得した IP アドレスと sessionId をログに記録する必要があります。詳細については、「セッショントレーシングソリューションを使用して解決の問題をトラブルシューティングする」をご参照ください。