使用Retrofit无法连接API服务器的安卓开发问题求助
问题背景
使用Retrofit开发安卓应用时,无法连接到API服务器,且未获取到具体失败原因。已在Manifest中添加ACCESS_NETWORK_STATE和INTERNET权限,该API在浏览器中可正常访问。
错误日志截图:
相关代码
Retrofit接口代码:
@GET("seasons/now") suspend fun getCurrentSeason(@Query("page") page: Int = 1): Response<GenericResponse<DataItem>>
Retrofit实例创建代码:
@Provides @Singleton fun provideOkHttp(logger: HttpLoggingInterceptor) = OkHttpClient.Builder() .addInterceptor(logger) .connectTimeout(60, TimeUnit.SECONDS) .build() @Provides @Singleton fun provideJikanApi(okHttpClient: OkHttpClient): JikanApi = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build().create(JikanApi::class.java)
排查与解决步骤
升级日志拦截器的日志级别
当前仅添加了HttpLoggingInterceptor但未指定日志级别,默认级别无法输出完整的请求/响应细节。将日志级别设为BODY,能在Logcat中看到真实请求地址、头信息、响应状态等关键内容:fun provideLoggingInterceptor() = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }校验BASE_URL格式
Retrofit要求baseUrl必须以/结尾,比如正确格式应为https://api.jikan.moe/v4/。如果缺少末尾斜杠,拼接接口路径时会出现地址错误(例如变成https://api.jikan.moe/v4seasons/now)。捕获异常并打印完整栈信息
调用suspend函数时用try-catch包裹,不仅要处理Response的失败状态,还要捕获IOException等异常,打印完整栈轨迹才能定位根本问题:try { val response = jikanApi.getCurrentSeason() if (response.isSuccessful) { // 处理成功逻辑 } else { Log.e("API_ERROR", "请求失败,状态码:${response.code()},响应体:${response.errorBody()?.string()}") } } catch (e: Exception) { Log.e("API_EXCEPTION", "请求异常", e) }检查网络安全配置(Android 9+)
如果API使用HTTP协议(非HTTPS),Android 9及以上默认禁止明文网络请求。需在res/xml/network_security_config.xml中配置允许:<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>并在Manifest的
<application>标签中添加:android:networkSecurityConfig="@xml/network_security_config"。若为HTTPS,需检查服务器证书是否有效,是否存在证书信任问题。排除代理/VPN干扰
开发时若启用了代理,可能导致请求无法正常发送。可暂时关闭代理,或为OkHttp配置对应代理信息:val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("proxy_host", 8080)) OkHttpClient.Builder() .proxy(proxy) // 其他配置
内容的提问来源于stack exchange,提问作者lelestacia

