本文介绍如何在已使用UC U4内核的应用中集成使用HTTPDNS。
UC U4内核是阿里巴巴集团开发的高性能移动端Webview解决方案,基于Chromium内核深度优化,提供了比系统Webview更快的页面加载速度和更好的兼容性。该内核广泛应用于淘宝、支付宝等应用中,经过了大规模商业化验证,详细介绍请参见UC引擎官网。
技术背景
随着移动互联网的快速发展,Webview在Android应用中扮演着越来越重要的角色。对于已经接入UC内核的开发者来说,虽然UC内核本身提供了优秀的渲染性能,但DNS解析仍然是影响Web安全和页面加载性能的关键因素。通过集成阿里云 HTTPDNS SDK,可以解决诸多Local DNS的问题,参见产品优势。
本文档旨在帮助已经接入UC U4内核的开发者,通过集成HTTPDNS SDK进一步优化应用的DNS安全和性能,提升Webview页面加载体验。
环境要求
UC 内核版本:5.18.10.0.250813181008 及以上
Android API Level:19+
支持架构:arm64-v8a, armeabi-v7a
UC内核是商业化产品,需要获取有效的授权密钥(AuthKey)才能正常使用。如需申请授权,请联系UC引擎官方授权服务。
集成步骤
1. 集成UC U4内核
由于本文档主要面向已经接入UC U4内核的用户,这里仅做简要说明。如果您还未接入UC内核,请参考官方文档进行完整的集成配置。
在Application中初始化UC U4内核:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// 初始化 UC 内核
U4Engine.createInitializer()
.setContext(this)
.setAuthKey("your_auth_key") // 替换为您的授权密钥
.setClient(object : InitializerClient() {
override fun onSuccess(info: IRunningCoreInfo) {
Log.d("UCWebView", "UC 内核初始化成功")
}
override fun onFailed(info: IRunningCoreInfo) {
Log.e("UCWebView", "UC 内核初始化失败: ${info.failedInfo()}")
}
})
.start()
}
}
2. 接入HTTPDNS SDK
详细步骤请参考Android SDK接入。以下为简要说明:
2.1 添加依赖
在app/build.gradle
中添加 HTTPDNS SDK 依赖:
dependencies {
implementation "com.aliyun.ams:alicloud-android-httpdns:${httpdnsVersion}"
}
2.2 初始化HTTPDNS服务
在Application中初始化HTTPDNS:
private fun initHttpDns() {
val accountId = "your_account_id" // 替换为您的 Account ID
val secretKey = "your_secret_key" // 可选,替换为您的 Secret Key
val initConfig = InitConfig.Builder()
.setEnableHttps(true)
.setEnableCacheIp(true)
.setEnableExpiredIp(true)
.build()
HttpDns.init(accountId, initConfig)
}
更多HTTPDNS配置选项说明,请参考:基础配置接口
3. 使用DnsService托管DNS服务
通常,在App中会有类似WebviewActivity / WebviewFragment等对Webview进行统一管理的入口类,可以在其中启用DNS托管服务并设置自定义域名解析器,示例如下:
import alibaba.httpdns_android_demo.databinding.ActivityWebviewBinding
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.sdk.android.httpdns.RequestIpType
import com.uc.webview.export.WebViewClient
import com.uc.webview.export.extension.DnsService
import com.uc.webview.export.extension.GlobalSettings
import com.uc.webview.export.extension.SettingKeys
import java.net.InetAddress
class WebviewActivity : AppCompatActivity() {
private lateinit var binding: ActivityWebviewBinding
private val TAG = "WebviewActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityWebviewBinding.inflate(layoutInflater)
setContentView(binding.root)
// 启用 DNS 托管服务
GlobalSettings.set(SettingKeys.EnableDnsHostingService, true)
// 设置HTTPDNS域名解析器
DnsService.setDoaminResolver(object : DnsService.IDomainResolver() {
override fun resolve(domain: String, extraInfos: Map<String, String>?): Array<String>? {
return resolveDomainWithHttpDns(domain, extraInfos)
}
})
// 配置并加载页面
configureWebview()
binding.webview.loadUrl("https://xxx.xxx.xxx")
}
private fun resolveDomainWithHttpDns(
domain: String,
extraInfos: Map<String, String>?
): Array<String>? {
if (domain.isBlank()) {
return null
}
// 获取 HTTPDNS 服务实例
val httpDnsService = HttpDns.getService(applicationContext, "your_account_id")
try {
// 使用 HTTPDNS 解析,推荐使用同步非阻塞接口
val result = httpDnsService?.getHttpDnsResultForHostSyncNonBlocking(
domain,
RequestIpType.auto,
extraInfos ?: emptyMap(),
null
)
if (result != null) {
val ipList = mutableListOf<String>()
// 添加 IPv4 和 IPv6 地址。U4内核会按序使用。
ipList.addAll(result.ips.filter { it.isNotBlank() })
ipList.addAll(result.ipv6s.filter { it.isNotBlank() })
if (ipList.isNotEmpty()) {
Log.d(TAG, "HTTPDNS 解析成功: $domain -> ${ipList.joinToString(", ")}")
return ipList.toTypedArray()
}
}
} catch (e: Exception) {
Log.w(TAG, "HTTPDNS 解析失败: $domain", e)
}
// 无结果时,降级到本地 DNS
return try {
val addresses = InetAddress.getAllByName(domain)
val ipAddresses = addresses.mapNotNull { it.hostAddress }
Log.d(TAG, "Local DNS 解析: $domain -> ${ipAddresses.joinToString(", ")}")
ipAddresses.toTypedArray()
} catch (e: Exception) {
Log.e(TAG, "Local DNS 解析失败: $domain", e)
null
}
}
private fun configureWebview() {
binding.webview.settings.apply {
javaScriptEnabled = true
domStorageEnabled = true
loadWithOverviewMode = true
useWideViewPort = true
}
}
}
总结
集成过程相对简单,只需要在现有的UC内核基础上添加HTTPDNS SDK依赖,并通过UC内核提供的 DNS 托管接口进行集成即可。建议在生产环境部署前进行充分测试,验证各种网络环境下的性能表现。