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"
如果不想全局允许明文请求,也可以针对目标域名配置:
- 创建
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>
- 在
AndroidManifest.xml的<application>中引用:
android:networkSecurityConfig="@xml/network_security_config"
内容的提问来源于stack exchange,提问作者David Frick
相关产品推荐
相关产品推荐

