Estou usando o JSoup para analisar um site (tive que configurá-lo para usar solicitações de texto não criptografado, pois https não é compatível). É uma forma Runnable
de evitar o bloqueio do thread da rede principal. No entanto, ele não parece ser exibido quando executo meu código. Suspeito que tenha algo a ver activity
(já que tive problemas para configurá-lo) e que estou usando uma classe interna, mas nenhum erro ou aviso é retornado. O que estou fazendo de errado?
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()
//val jsonData = finraGetBondInfo("Boeing")
}
private fun setupData() {
val thread = Thread(Task()).start()
}
inner class Task() : Runnable {
override fun run() {
val doc = Jsoup.connect("http://openinsider.com/search?q=GME").get()
val table = doc.select(".tinytable")
// Get the table header cells
val tableHeaderRow = TableRow(activity)
tableHeaderRow.isClickable = true
table.select("thead").select("tr").forEach {row ->
row.getElementsByTag("th").forEach { cell ->
Log.d("CELL text", cell.text())
val textView = TextView(activity)
textView.text = cell.text()
tableHeaderRow.addView(textView)
}
}
// Get the table body cells
table.select("tbody").select("tr").forEach {row ->
val tableRow = TableRow(requireActivity())
tableRow.isClickable = true
row.getElementsByTag("td").forEach { cell ->
val textView = TextView(activity)
textView.text = cell.text()
tableRow.addView(textView)
}
}
}
}
}
Seu método run() atualmente atualiza a UI criando elementos TextView e adicionando-os às linhas da tabela. As atualizações da UI devem sempre ser realizadas no thread principal. Você pode usar o método runOnUiThread() para executar código que atualiza a IU no thread principal.
Não é assim que eu implementaria, mas se você quiser uma solução rápida, você deve usar o código abaixo:
Seguindo o que @snachmsm disse, atualizei meu código para usar código assíncrono em vez de Runnable. Separei a obtenção dos dados e o desenho da UI, o que faz mais sentido.
É assim que você pode trabalhar
openinsiderGetData()
corretamente em um thread em segundo plano usando uma corrotina.