Android Kotlin中使用InputStream实现HTTP GET请求崩溃求助
解决Android中GET请求崩溃的问题
崩溃原因
你的三段代码全部在主线程执行了同步网络请求,而Android从API 11开始严格禁止主线程进行网络操作,会抛出NetworkOnMainThreadException导致崩溃。这是Android为避免主线程阻塞、保证UI流畅性的强制规范。
解决方案
1. 使用Kotlin协程(推荐,现代Android开发标准)
给网络请求函数添加suspend修饰符,通过协程在后台线程执行请求,再切换回主线程处理结果:
修改第一段HttpURLConnection代码:
// 给函数添加suspend修饰,指定IO线程执行 suspend fun readURL(urlString: String): String = withContext(Dispatchers.IO) { var response = "" val url = URL(urlString) val connection = url.openConnection() as HttpURLConnection connection.requestMethod = "GET" // 使用use自动关闭流,避免资源泄漏 BufferedReader(InputStreamReader(connection.inputStream)).use { reader -> var inputLine: String? while (reader.readLine().also { inputLine = it } != null) { response += inputLine } } connection.disconnect() response } // 在Activity/Fragment中调用(需在CoroutineScope内,比如lifecycleScope) lifecycleScope.launch { try { val result = readURL("你的目标URL") // 在主线程处理请求结果,比如更新UI Log.d("NetworkResult", result) } catch (e: Exception) { e.printStackTrace() } }
修改第三段OkHttp代码:
suspend fun get(url: String): InputStream? = withContext(Dispatchers.IO) { val client = OkHttpClient() val request = Request.Builder() .url(url) .build() // 使用use自动关闭response client.newCall(request).execute().use { response -> if (response.isSuccessful) { response.body?.byteStream() } else { null } } } // 调用方式同上 lifecycleScope.launch { try { val inputStream = get("你的目标URL") // 处理输入流数据 } catch (e: Exception) { e.printStackTrace() } }
2. 使用OkHttp异步请求(回调方式)
如果不想用协程,可使用OkHttp的enqueue方法做异步请求,避免阻塞主线程:
fun getAsync(url: String) { val client = OkHttpClient() val request = Request.Builder() .url(url) .build() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // 请求失败处理 e.printStackTrace() } override fun onResponse(call: Call, response: Response) { response.use { if (it.isSuccessful) { val inputStream = it.body?.byteStream() // 后台线程处理数据,如需更新UI需切回主线程 runOnUiThread { // 执行UI更新操作 } } } } }) }
额外注意事项
- 若目标API为Android 9(API 28)及以上,默认禁止明文HTTP请求。若使用HTTP链接,需在
AndroidManifest.xml的application标签内添加:
优先推荐使用HTTPS链接。android:usesCleartextTraffic="true" - 确保已添加必要网络权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
内容的提问来源于stack exchange,提问作者Binary
相关产品推荐
相关产品推荐

