You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Retrofit开发Android Widget时遇UnknownHostException求助

问题:Android Widget真机网络请求失败(UnknownHostException)

开发一款Android Widget用于展示Github Pages托管的JSON数据,使用Retrofit实现网络请求。在Android Studio模拟器中运行正常,但生成APK安装到真机后出现错误:

java.net.UnknownHostException: Unable to resolve host "host": No Address associated

尝试请求google.com同样无法解析主机,已在Manifest中添加以下权限但问题未解决:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Retrofit代码实现

@Keep
object RetrofitService {

    private val numbersRetrofit: Retrofit = Retrofit.Builder()
        .baseUrl("https://host.github.io/")
        .client(OkHttpClient())
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    fun getGamesApiService(): GamesApiService {
        return numbersRetrofit.create(GamesApiService::class.java)
    }

}

更新:网络状态检测结果

使用以下方法检测网络状态,返回netInfo.isConnected为false:

private fun isOnline(mgr: ConnectivityManager): Boolean {
    val netInfo = mgr.activeNetworkInfo
    return if (netInfo != null && netInfo.isConnected) {
        true
    } else false
}

解决方法

1. 修复网络状态检测逻辑(适配Android 10+)

activeNetworkInfo在API 29已被废弃,且无法准确判断网络是否可正常访问。改用NetworkCapabilities检测:

private fun isOnline(context: Context): Boolean {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetwork = connectivityManager.activeNetwork ?: return false
    val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
    
    // 验证网络是否具备互联网访问能力且已通过验证
    return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
           networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}

2. 适配Android后台网络访问限制

Widget属于后台组件,Android 8.0+对后台网络请求有严格限制:

  • 改用WorkManager调度网络请求:避免在Widget的onUpdate中直接发起请求,通过WorkManager在后台执行网络操作,完成后更新Widget数据。
  • 合理申请权限(可选):若需长期后台同步,可在Manifest中为相关组件添加android:foregroundServiceType="dataSync",或申请ACCESS_BACKGROUND_LOCATION权限(需用户授权),注意合规性。

3. 优化OkHttpClient配置

添加超时设置并指定DNS服务器,避免真机DNS解析异常:

val okHttpClient = OkHttpClient.Builder()
    .dns(Dns.SYSTEM) // 或自定义DNS:Dns.Builder().add("8.8.8.8").build()
    .connectTimeout(30, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .writeTimeout(30, TimeUnit.SECONDS)
    .build()

4. 检查网络安全配置(Android 9+)

若存在域名访问限制,在res/xml/network_security_config.xml中添加配置:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">github.io</domain>
    </domain-config>
</network-security-config>

并在Manifest的application标签中引用:

android:networkSecurityConfig="@xml/network_security_config"

5. 验证APK混淆规则

若使用release构建,确保Retrofit相关类未被混淆,在proguard-rules.pro中添加:

-keep class retrofit2.** { *; }
-keep interface retrofit2.** { *; }
-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}
-keep class com.yourpackage.GamesApiService { *; } // 替换为你的接口类路径

6. 排查真机本地网络问题

  • 切换网络环境:尝试切换WiFi/移动数据,排除单一网络故障。
  • 手动设置DNS:将真机DNS改为公共DNS(如8.8.8.8、1.1.1.1),测试域名解析是否正常。

内容的提问来源于stack exchange,提问作者Marco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 16:34:55