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

使用RETROFIT + COROUTINE发起网络请求无法获取数据无响应求助

问题排查&修复方案

1. 检查基础配置

  • 首先确认AndroidManifest.xml中已经添加网络权限,这是发起网络请求的必备条件:
<uses-permission android:name="android.permission.INTERNET" />

如果你的应用targetSdkVersion >=28且需要访问http接口,还需要在application标签下添加属性:

android:usesCleartextTraffic="true"

2. 补全异常捕获和日志逻辑

你现有代码仅处理了响应成功的场景,一旦出现网络不通、解析失败、接口返回非2xx状态码等情况,都没有任何日志输出,自然看不到相关信息。同时不建议直接使用GlobalScope,容易造成内存泄漏,推荐用lifecycleScope绑定Activity生命周期自动销毁。

首先在build.gradle(Module级)添加必要依赖:

dependencies {
    // lifecycle协程依赖,用于lifecycleScope
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2"
    // OkHttp日志拦截器,可打印完整的请求、响应信息
    implementation "com.squareup.okhttp3:logging-interceptor:4.11.0"
}

修改后的Activity代码如下:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.lifecycle.lifecycleScope
import com.google.gson.annotations.SerializedName
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET

class MainActivity : AppCompatActivity() {
    val TAG = "MainActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 配置日志拦截器,打印全量请求响应信息
        val loggingInterceptor = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }
        val okHttpClient = OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .build()

        val api = Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl("https://howtodoandroid.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(RetrofitService::class.java)

        // 用lifecycleScope代替GlobalScope,避免内存泄漏
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                val response = api.getAllMovies()
                Log.d(TAG, "接口响应码:${response.code()}")
                if (response.isSuccessful) {
                    val movies = response.body()
                    Log.d(TAG, "响应体是否为空:${movies == null}")
                    movies?.forEach { movie ->
                        Log.d(TAG, "电影名称:${movie.name}")
                    }
                } else {
                    // 打印失败响应的错误信息
                    Log.e(TAG, "请求失败,错误信息:${response.errorBody()?.string()}")
                }
            } catch (e: Exception) {
                // 捕获所有异常:网络异常、解析异常等
                Log.e(TAG, "请求抛出异常:", e)
            }
        }
    }
}

interface RetrofitService {
    @GET("movielist.json")
    suspend fun getAllMovies() : Response<List<Movie>>
}

// 如果接口返回字段和定义不一致,可加@SerializedName注解映射
data class Movie(
    val name: String, 
    val imageUrl: String, 
    val category: String
)

3. 核对数据类和接口返回的匹配性

如果接口返回的字段名、字段类型和你定义的Movie数据类不匹配,Gson解析会直接抛出异常,没有捕获的话也不会有输出。可以通过日志拦截器打印的返回结果,核对字段是否匹配,必要时用@SerializedName做字段映射。

修改后运行App,查看Logcat的日志即可定位具体问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:36:03