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

Runnable中Activity的使用问题?Android表格无法显示故障排查

问题分析与修复方案

核心问题点

  • 子线程操作UI无效:Android禁止在非主线程操作UI组件,你在Runnable子线程里创建TableRow、TextView的操作不会生效,也不会抛出明显异常。
  • 生成的行未添加到布局:你创建了表头和表体的行,但没把这些行放到Fragment对应的表格容器(比如binding里的TableLayout)中,自然看不到内容。
  • 明文HTTP请求未授权:Android 9+默认拦截明文HTTP请求,你访问的是http地址,必须配置允许明文请求,否则JSoup根本拿不到网页数据。
  • 上下文使用有风险:子线程直接用activity可能因为Fragment生命周期变化导致上下文为空,建议用requireContext()获取稳定上下文。

修改后的完整代码

package com.example.investmenthuntermobile

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TableRow
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.example.investmenthuntermobile.databinding.InsiderFragmentBinding
import org.jsoup.Jsoup

class InsiderFragment : Fragment() {

    private lateinit var binding: InsiderFragmentBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = InsiderFragmentBinding.inflate(layoutInflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setupData()
    }

    private fun setupData() {
        Thread(Task()).start()
    }

    inner class Task : Runnable {
        override fun run() {
            try {
                // 1. 子线程中仅做数据抓取与解析
                val doc = Jsoup.connect("http://openinsider.com/search?q=GME").get()
                val table = doc.select(".tinytable")

                // 收集表头文本
                val headerCells = mutableListOf<String>()
                table.select("thead tr th").forEach { cell ->
                    headerCells.add(cell.text())
                    Log.d("CELL text", cell.text())
                }

                // 收集表体每行的文本
                val bodyRows = mutableListOf<List<String>>()
                table.select("tbody tr").forEach { row ->
                    val rowCells = mutableListOf<String>()
                    row.select("td").forEach { cell ->
                        rowCells.add(cell.text())
                    }
                    bodyRows.add(rowCells)
                }

                // 2. 切回主线程更新UI
                requireActivity().runOnUiThread {
                    // 创建并添加表头行
                    val headerRow = TableRow(requireContext())
                    headerRow.isClickable = true
                    headerCells.forEach { text ->
                        val tv = TextView(requireContext())
                        tv.text = text
                        tv.setPadding(8, 8, 8, 8) // 添加上下左右内边距,避免文字挤在一起
                        headerRow.addView(tv)
                    }
                    // 假设你的布局里有id为insiderTable的TableLayout,替换成你实际的id
                    binding.insiderTable.addView(headerRow)

                    // 创建并添加表体每行
                    bodyRows.forEach { rowData ->
                        val tableRow = TableRow(requireContext())
                        tableRow.isClickable = true
                        rowData.forEach { text ->
                            val tv = TextView(requireContext())
                            tv.text = text
                            tv.setPadding(8, 8, 8, 8)
                            tableRow.addView(tv)
                        }
                        binding.insiderTable.addView(tableRow)
                    }
                }

            } catch (e: Exception) {
                // 捕获异常方便排查,避免崩溃也看不到报错
                Log.e("InsiderFragment", "处理失败", e)
            }
        }
    }
}

必须的明文请求配置

在AndroidManifest.xml的<application>标签里添加:

android:usesCleartextTraffic="true"

如果不想全局允许明文请求,也可以针对目标域名配置:

  1. 创建res/xml/network_security_config.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">openinsider.com</domain>
    </domain-config>
</network-security-config>
  1. 在AndroidManifest.xml的<application>中引用:
android:networkSecurityConfig="@xml/network_security_config"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:00:38