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

Android Studio中JSoup获取Span值时应用崩溃问题求助

解决JSoup网络请求导致APP闪退的问题

嘿,我来帮你搞定这个问题!首先咱们得理清两个核心问题:你看到的IOException是编译层面的要求,而APP闪退的真正元凶是Android禁止在主线程(UI线程)执行网络操作——这会触发NetworkOnMainThreadException,直接导致APP崩溃。

问题拆解

  • 编译时的Unhandled exception java.io.IOException:JSoup的connect(url).get()方法声明会抛出IOException,Java语法要求必须显式处理(要么用try-catch包裹,要么让方法抛出异常)。
  • 运行时闪退:Android从API 11开始就严格禁止主线程做网络请求,你的代码肯定是在Activity的onCreate或其他主线程方法里直接调用JSoup,这就触发了崩溃。

解决方案步骤

1. 先添加网络权限

首先确保你的AndroidManifest.xml里配置了网络权限,不然网络请求根本发不出去:

<uses-permission android:name="android.permission.INTERNET" />

2. 把JSoup请求放到后台线程

这里给你两种常用的实现方式,按需选择:

方式一:用AsyncTask(Java传统方案)

把网络请求放到AsyncTask的后台方法中执行,完成后再回到主线程更新UI:

package com.example.antalnndor.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import org.jsoup.nodes.Document;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    private TextView resultTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        resultTextView = findViewById(R.id.your_textview_id);

        // 启动后台任务执行网络请求
        new FetchSpanTask().execute("你的目标网页URL");
    }

    // AsyncTask<传入参数类型, 进度更新类型, 返回结果类型>
    private class FetchSpanTask extends android.os.AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {
            String spanValue = "";
            try {
                // 后台线程执行网络请求与解析
                Document doc = Jsoup.connect(urls[0]).get();
                // 替换成你要定位的Span标签选择器,比如按class/id
                Element spanElement = doc.select("span.your-span-class").first();
                if (spanElement != null) {
                    spanValue = spanElement.text();
                }
            } catch (IOException e) {
                e.printStackTrace();
                spanValue = "请求失败:" + e.getMessage();
            }
            return spanValue;
        }

        @Override
        protected void onPostExecute(String result) {
            // 回到主线程更新UI
            resultTextView.setText(result);
        }
    }
}
方式二:用Coroutines(Kotlin现代方案)

如果你的项目用Kotlin,推荐用协程,代码更简洁易维护:

// 先确保build.gradle里添加协程依赖
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'

class MainActivity : AppCompatActivity() {
    private lateinit var resultTextView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        resultTextView = findViewById(R.id.your_textview_id)

        // 启动协程,自动绑定生命周期
        lifecycleScope.launch {
            val spanValue = withContext(Dispatchers.IO) {
                var value = ""
                try {
                    val doc = Jsoup.connect("你的目标网页URL").get()
                    val spanElement = doc.select("span.your-span-class").first()
                    value = spanElement?.text() ?: ""
                } catch (e: IOException) {
                    e.printStackTrace()
                    value = "请求失败:${e.message}"
                }
                value
            }
            // 回到主线程更新UI
            resultTextView.text = spanValue
        }
    }
}

关键注意点

  • 永远不要在主线程执行网络、文件IO这类耗时操作,会导致APP卡顿甚至崩溃。
  • 处理JSoup异常时,建议给用户显示友好的提示,而不是只打印日志。
  • 如果需要处理复杂的网络场景,也可以考虑用Retrofit配合JSoup,但简单网页解析用上面的方案完全足够。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:42:21