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

Kotlin中使用Retrofit调用JSON API无响应问题排查

问题分析与修复方案

你的代码核心问题是只创建了Retrofit的Call对象,但根本没发起实际的网络请求,所以自然看不到任何响应或日志输出。下面一步步给你修正:

1. 触发网络请求

Retrofit的Call对象只是请求的"蓝图",必须调用enqueue()(异步推荐)或者execute()(同步,禁止在主线程调用)才能真正发起请求。

改成异步请求的写法示例:

fun getURL(url: String) {
    val retrofit = Retrofit.Builder()
        .baseUrl(url)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    val service = retrofit.create(APIService::class.java)
    val dataCall = service.listRepos()

    // 发起异步请求,回调在主线程执行
    dataCall.enqueue(object : Callback<Any?> {
        override fun onResponse(call: Call<Any?>, response: Response<Any?>) {
            if (response.isSuccessful) {
                val responseData = response.body()
                Log.d("PRINT_JSON_HERE", "响应数据: $responseData")
                // 后续替换成你的data class后,在这里处理业务逻辑
            } else {
                Log.e("PRINT_JSON_HERE", "请求失败,状态码: ${response.code()}")
            }
        }

        override fun onFailure(call: Call<Any?>, t: Throwable) {
            Log.e("PRINT_JSON_HERE", "请求出错: ${t.message}")
        }
    })
}

2. ViewModel中的网络请求规范

ViewModel里直接写网络请求不利于维护,还要避免阻塞主线程,推荐用Kotlin协程(Retrofit 2.6+支持挂起函数):

  • 先修改API接口为挂起函数:
interface APIService {
    @GET("cursor/popular/10")
    suspend fun listRepos(): Response<Any?> // 用Response包裹可获取状态码等信息
}
  • 然后在ViewModel里用viewModelScope发起协程:
class YourViewModel : ViewModel() {
    // 全局复用Retrofit实例,不要每次调用都创建
    private val retrofit by lazy {
        Retrofit.Builder()
            .baseUrl("你的基础URL") // 建议把baseUrl固定,不要每次传参
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
    private val apiService = retrofit.create(APIService::class.java)

    fun fetchData() {
        viewModelScope.launch {
            try {
                val response = apiService.listRepos()
                if (response.isSuccessful) {
                    val data = response.body()
                    Log.d("PRINT_JSON_HERE", "响应数据: $data")
                } else {
                    Log.e("PRINT_JSON_HERE", "请求失败: ${response.code()}")
                }
            } catch (e: Exception) {
                Log.e("PRINT_JSON_HERE", "请求异常: ${e.message}")
            }
        }
    }
}

这种写法符合Android生命周期规范,不会因为页面销毁导致内存泄漏。

3. 其他优化点

  • BaseUrl必须以/结尾:Retrofit要求基础URL的最后必须是斜杠,比如https://your-api-domain.com/,否则路径拼接会出错。
  • 尽快替换Any?为具体data class:用Any?会丢失类型安全,Gson解析也容易出问题,建议用工具(比如QuickType)把接口返回的JSON转换成对应的Kotlin data class。
  • 不要重复创建Retrofit实例:Retrofit初始化成本高,全局单例或者在ViewModel里懒加载复用更高效。

内容的提问来源于stack exchange,提问作者Heron. F

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:05:18