Kotlin开发Android中Jsoup.connect触发NetworkOnMainThreadException崩溃
崩溃根本原因
- 该问题和Jsoup依赖配置、项目构建状态无关,清理重建项目无法解决。
- 触发的
android.os.NetworkOnMainThreadException是Android平台的硬性规则限制:API 11及以上版本,系统禁止在主线程(UI线程)执行任何耗时的网络IO操作,防止阻塞UI线程导致应用无响应。 - 你当前的代码将Jsoup的同步阻塞式
get()请求直接写在MySignOff页面的onCreate方法中,而onCreate本身就运行在应用主线程,触发规则后系统直接抛出异常终止应用运行。
实际可落地的解决操作
方案1:使用原生子线程执行请求
将网络请求逻辑从主线程移出,放到独立子线程中执行,拿到解析结果后如果需要更新页面UI,再切回主线程操作:
// 替换原来在onCreate里直接调用Jsoup的代码 Thread { val doc = try { Jsoup.connect("https://www.google.com").get() } catch (e: Exception) { // 捕获网络异常:比如无网络、地址访问受限等情况 null } // 切回主线程处理解析结果、更新UI runOnUiThread { if (doc != null) { // 写入你的页面数据处理逻辑 } } }.start()
注意:直接新建子线程的写法需要手动处理页面销毁后的线程停止逻辑,避免内存泄漏。
方案2:使用Kotlin协程(Kotlin项目推荐写法)
协程是Kotlin官方推荐的异步实现方案,可自动绑定页面生命周期,避免线程泄漏,写法更简洁:
- 确认项目已经引入AndroidX的生命周期协程依赖(通常Android Studio新建Kotlin项目会默认集成):
lifecycle-runtime-ktx - 替换代码逻辑为:
lifecycleScope.launch(Dispatchers.IO) { // 切换到IO线程执行网络请求 val doc = try { Jsoup.connect("https://www.google.com").get() } catch (e: Exception) { null } // 切回主线程处理UI逻辑 withContext(Dispatchers.Main) { if (doc != null) { // 写入你的页面数据处理逻辑 } } }
额外前置检查项
- 确认已经在
AndroidManifest.xml中声明网络权限:<uses-permission android:name="android.permission.INTERNET" />,未声明权限时即使将请求移到子线程,也会触发权限报错,这和当前的主线程崩溃是两个独立的异常。 - 不要尝试通过修改
StrictMode配置关闭主线程网络检查来绕过规则,这种操作会导致UI卡顿、ANR,不符合平台开发规范。
内容的提问来源于stack exchange,提问作者Cheng Poh
相关产品推荐
相关产品推荐

