将带有 jsoup 的 HTML 表解析为 android listview
Posted
技术标签:
【中文标题】将带有 jsoup 的 HTML 表解析为 android listview【英文标题】:Parsing a HTML table with jsoup to android listview 【发布时间】:2015-12-18 17:04:26 【问题描述】:我正在开发一个需要 html 表的应用程序。经过大量努力寻找正确的代码并解决错误。我遇到了一个错误,我不知道如何解决它。我已经发现我需要一个扩展 Async 的类。唯一的问题是我真的不知道如何使用异步。我得到的错误是 Async 的致命异常:“FATAL EXCEPTION: AsyncTask #1”。这不太清楚下一步该做什么或如何解决这个问题。所以我希望有人可以帮助我。
最后的代码是将表格放入ArrayList,最后放入列表视图。
这是我的代码:
public class Cluka2 extends AsyncTask<Void, Void, String>
Document document = null;
public ArrayList<String> list = new ArrayList<>();
@Override
protected String doInBackground(Void... params)
try
document = Jsoup.connect("https://tennisnaarden.planmysport.com/portal/page/pmsportal30/TVNaarden/Toernooien/Clubtoernooi").get();
// System.out.println(document);
// Log.e("DEBUG", document.toString());
// Log.v("Debug", document.toString());
catch (IOException e)
e.printStackTrace();
Elements elements = document.select("#pcnt1383_8158836_1383_4326089_4326089 td:first-child");
for(int i=0;i<elements.size();i++)
list.add(elements.get(i).text());
System.out.println(elements.get(i).text());
System.out.println(list);
return list.toString();
这是我的错误:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.NullPointerException
at com.example.gebruiker.tvnaardentoernooien.Cluka2.doInBackground(Cluka2.java:29)
at com.example.gebruiker.tvnaardentoernooien.Cluka2.doInBackground(Cluka2.java:12)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
【问题讨论】:
您应该在代码中显示第 29 行在哪里。 【参考方案1】:看起来您在尝试连接到提到的网站页面时遇到异常,然后控制转到 catch 块,之后您访问的是未初始化的变量 document ,这就是为什么你会收到NPE。
使用 throws 或只是运行时包装技巧来找到真正的原因:
catch (IOException e)
throw new RuntimeException(e);
【讨论】:
【参考方案2】:阿罗哈,
将您要求的代码放入 try catch 语句中。当您尝试在 try catch 语句之外使用它时,您的变量超出了范围。第 29 行的对象 Elements 试图引用最初声明的 Document 对象,该对象仍然为空。那应该让它为你工作。
public class Cluka2 extends AsyncTask<Void, Void, String>
Document document = null;
public ArrayList<String> list = new ArrayList<>();
@Override
protected String doInBackground(Void... params)
try
document = Jsoup.connect("https://tennisnaarden.planmysport.com/portal/page/pmsportal30/TVNaarden/Toernooien/Clubtoernooi").get();
// System.out.println(document);
// Log.e("DEBUG", document.toString());
// Log.v("Debug", document.toString());
Elements elements = document.select("#pcnt1383_8158836_1383_4326089_4326089 td:first-child");
for(int i=0;i<elements.size();i++)
list.add(elements.get(i).text());
System.out.println(elements.get(i).text());
System.out.println(list);
return list.toString();
catch (IOException e)
e.printStackTrace();
您的代码应如上所示。您对文档检索到的数据所做的任何工作都应在 try catch 中处理。此外,由于您要将这些元素添加到 arraylist,它也需要在 try catch 中。这应该可以防止您的空指针异常被触发。至于您的 AsyncTask,只需记住 AsyncTask 的生命周期(onPreExecute、doInBackground、postExecute 和 onProgressUpdate)就可以了。
【讨论】:
感谢您的帮助。 NullPointerException 消失了,但现在唯一的问题是从网站检索数据。我现在有一个没有数据的空白页。 为了访问您的数据,您需要在 onPostExecute 中检索它。更多详情请查看AsyncTask methods on Android Developer【参考方案3】:经过一番努力,这是我解决问题的方法:
这是我的类,用于连接 URL 并获取 html 数据
public class ClubkampioenschappenOnderdelenHTMLRequest extends AsyncTask<Void, Void, String>
Document document = null;
public List<String> list = new ArrayList<>();
private ListView listView;
private Context context = null;
public ClubkampioenschappenOnderdelenHTMLRequest(ArrayList<String> list, Context mContext, ListView ListView)
this.list = list;
context= mContext;
this.listView = ListView;
public List<String> getList()
return list;
public void setList(List<String> list)
this.list = list;
@Override
protected String doInBackground(Void... params)
try
URL url = new URL("https://tennisnaarden.planmysport.com/portal/page/pmsportal30/TVNaarden/Toernooien/Clubtoernooi");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "text/html");
conn.connect();
InputStreamReader input = new InputStreamReader((InputStream) conn.getContent());
BufferedReader reader = new BufferedReader(input);
String line;
String html = "";
while((line = reader.readLine()) != null)
html += line;
document = Jsoup.parse(html);
Elements elements = document.select("#pcnt1383_8158836_1383_4326089_4326089 td:first-child");
for (int i = 0; i < elements.size(); i++)
list.add(elements.get(i).text());
catch (IOException e)
e.printStackTrace();
return list.toString();
@Override
protected void onPostExecute(String result)
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, list);
listView.setAdapter(arrayAdapter);
onCreate方法中的代码:
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_clubkampioenschappen_singleen_dubbel);
this.setTitle("Onderdelen");
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
ListView Onderdelen = (ListView) findViewById(R.id.Onderdelen);
ClubkampioenschappenOnderdelenHTMLRequest clucka = new ClubkampioenschappenOnderdelenHTMLRequest(list, ClubkampioenschappenSingleenDubbelOnderdelen.this, Onderdelen);
clucka.execute();
【讨论】:
以上是关于将带有 jsoup 的 HTML 表解析为 android listview的主要内容,如果未能解决你的问题,请参考以下文章