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

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标签内添加:
    android:usesCleartextTraffic="true"
    
    优先推荐使用HTTPS链接。
  • 确保已添加必要网络权限:
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:46:59