使用OkHttp发起非HTTPS请求时触发NetworkOnMainThreadException求助
解决OkHttp+协程调用HTTP API时的NetworkOnMainThreadException问题
问题根源
你当前的代码里,client.newCall().execute()确实在Dispatchers.IO线程执行,但response.body!!.string()是在Dispatchers.Main线程调用的。OkHttp的ResponseBody.string()并非纯内存操作——它会实际读取网络输入流中的数据,这属于网络IO操作,在主线程执行必然触发NetworkOnMainThreadException。
修复方案
把所有涉及网络IO的操作(包括读取响应体)都包裹在withContext(Dispatchers.IO)中,只将最终结果带回主线程处理UI逻辑:
val baseURL = "http://192.168.1.100:5555/api" val authToken = "TOKEN" val client = OkHttpClient.Builder().cache( Cache(context.cacheDir, 20 * 1024 * 1024) ).build() CoroutineScope(Dispatchers.Main).launch { val url = baseURL.toHttpUrl() .newBuilder() .addPathSegments("compositions/search") .build() // 所有网络相关操作都在IO线程完成 val responseBody = withContext(Dispatchers.IO) { val request = Request.Builder() .get() .url(url) .addHeader("Authorization", "bearer $authToken") .build() client.newCall(request).execute().use { response -> // use块自动关闭response,避免资源泄漏 if (response.isSuccessful) { response.body?.string() ?: "" } else { // 按需处理错误场景 "" } } } // 回到主线程,处理响应内容(比如更新UI) // processResponse(responseBody) }
额外注意事项
- Android 9+明文HTTP限制:测试环境用HTTP API时,需配置允许明文请求:
- 在
res/xml目录创建network_security_config.xml:<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">192.168.1.100</domain> </domain-config> </network-security-config> - 在
AndroidManifest.xml的application标签添加:android:networkSecurityConfig="@xml/network_security_config"
- 在
- 资源泄漏防护:始终用
use块包裹Response对象,确保IO资源被正确释放。
内容的提问来源于stack exchange,提问作者user19073772
相关产品推荐
相关产品推荐

