Kotlin中如何捕获URL.readText()在无网络或URL不存在时的错误?
解决URL.readText()无响应的问题:添加超时与精准异常捕获
你遇到的核心问题是默认的URL连接没有设置超时时间,导致当无网络或目标URL不可达时,请求会一直挂起,既不会抛出异常也不会返回结果,你的try-catch自然也就没机会触发。下面是针对性的解决方案:
关键修改点
- 不要直接使用
URL.readText(),手动创建HttpURLConnection并设置连接超时和读取超时,让请求在超时后自动抛出异常。 - 检查HTTP响应码,比如404状态码可以直接捕获"目标URL不存在"的情况,不需要依赖异常。
- 分类型捕获异常,给用户更精准的错误提示(比如无网络、超时、其他IO错误)。
修改后的完整代码
doAsync { var json = "" try { val targetUrl = URL("http://10.0.2.2:8888/bac/orient.php?ort=1") // 手动打开HTTP连接 val connection = targetUrl.openConnection() as HttpURLConnection // 设置连接超时(5秒,单位:毫秒) connection.connectTimeout = 5000 // 设置读取超时(10秒,单位:毫秒) connection.readTimeout = 10000 // 明确请求方法为GET(默认就是GET,这里可写可不写,增加可读性) connection.requestMethod = "GET" // 检查响应码:200表示请求成功 if (connection.responseCode == HttpURLConnection.HTTP_OK) { // 使用use()自动关闭输入流,避免资源泄漏 json = connection.inputStream.bufferedReader().use { it.readText() } } else { // 处理非200的响应,比如404(URL不存在)、500(服务器错误)等 json = "请求失败:响应码${connection.responseCode}" } } catch (e: UnknownHostException) { // 无网络、域名无法解析时触发 e.printStackTrace() json = "无网络连接或目标地址不可达" } catch (e: SocketTimeoutException) { // 请求超时(连接或读取超时)时触发 e.printStackTrace() json = "请求超时,请稍后重试" } catch (e: IOException) { // 其他IO相关异常兜底(比如流读取失败) e.printStackTrace() json = "请求错误:${e.message ?: "未知错误"}" } catch (e: Exception) { // 捕获所有其他未知异常,避免崩溃 e.printStackTrace() json = "发生未知错误" } // 回到主线程显示提示 uiThread { toast(json) } }
额外说明
- 超时时间可以根据你的需求调整,比如网络环境差的话可以适当延长,但不要设得太长,否则用户会一直等待。
- 如果你的项目已经在使用Kotlin协程(Coroutines),推荐用
launch(Dispatchers.IO)替代doAsync,用withContext(Dispatchers.Main)替代uiThread,这是更现代的异步处理方式。 - 记得在AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />,否则连基本的网络请求都无法发起。
内容的提问来源于stack exchange,提问作者Ismail ackerboy
相关产品推荐
相关产品推荐

