Stetho+Chrome调试时REST请求一直Pending问题求助
Hey,我之前也踩过Stetho+Retrofit+OkHttp的这个坑!网络请求在Chrome里一直Pending,但直接访问URL没问题,大概率是配置环节出了问题,给你几个排查和解决的方向:
1. 检查Stetho拦截器的添加顺序和类型
OkHttp的拦截器执行顺序非常关键,Stetho的网络拦截器必须放在最后添加,而且要使用addNetworkInterceptor()而不是addInterceptor()。因为网络拦截器是在请求真正发送到服务器前后触发,更适合监控完整的网络请求链路。
正确的配置示例(Kotlin):
val okHttpClient = OkHttpClient.Builder() // 先添加你的自定义拦截器(如果有的话) .addInterceptor(AuthInterceptor()) // 最后添加Stetho的网络拦截器 .addNetworkInterceptor(StethoInterceptor()) .build() // 关联到Retrofit val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build()
如果之前用了addInterceptor()添加Stetho拦截器,改成addNetworkInterceptor()试试,这是最常见的问题原因。
2. 排查OkHttp的缓存或其他请求配置
如果你的OkHttpClient配置了缓存,但缓存目录权限不足、缓存大小设置异常,可能会导致请求被阻塞在缓存处理环节。可以暂时注释掉缓存配置,测试是否恢复正常:
// 暂时注释掉缓存配置 val okHttpClient = OkHttpClient.Builder() // .cache(Cache(File(context.cacheDir, "http-cache"), 10 * 1024 * 1024)) .addNetworkInterceptor(StethoInterceptor()) .build()
如果去掉缓存后请求正常,那就是缓存配置的问题,需要检查缓存目录的读写权限。
3. 验证请求体和序列化配置
直接访问URL通常是GET请求,但你的APP里可能是POST/PUT等带请求体的请求。如果Retrofit的序列化配置有问题(比如GsonConverterFactory初始化错误、请求体字段不匹配),会导致请求无法正常发送,但不会抛出明显异常,只会卡在Pending状态。
可以先把请求改成GET测试,或者检查ConverterFactory的配置:
// 确保GsonConverterFactory正确初始化(如果用Gson的话) val gson = GsonBuilder() .setLenient() // 宽松模式,避免JSON格式严格校验导致的问题 .create() val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .build()
4. 检查Stetho和Chrome的版本兼容性
如果你的Stetho版本太老,而Chrome版本较新,可能会出现协议兼容性问题。建议更新Stetho到最新稳定版,当前最新的是1.5.1,Gradle依赖配置如下:
dependencies { implementation 'com.facebook.stetho:stetho:1.5.1' implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1' }
更新后重启APP和Chrome,再测试请求是否正常。
5. 排查SSL证书问题
如果你的服务器使用了自签名SSL证书,Chrome访问时会提示你信任证书,但Stetho的拦截器会因为证书验证失败而卡住请求。这种情况下,可以在调试环境下给OkHttp添加跳过SSL验证的配置(注意:上线必须移除!):
fun createDebugOkHttpClient(): OkHttpClient { return try { // 创建信任所有证书的TrustManager val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager { override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun getAcceptedIssuers(): Array<X509Certificate> = emptyArray() }) val sslContext = SSLContext.getInstance("SSL") sslContext.init(null, trustAllCerts, SecureRandom()) val sslSocketFactory = sslContext.socketFactory OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager) .hostnameVerifier { _, _ -> true } // 跳过主机名验证 .addNetworkInterceptor(StethoInterceptor()) .build() } catch (e: Exception) { throw RuntimeException(e) } }
内容的提问来源于stack exchange,提问作者deimian86

