I wrote a JSoup HTML scraping class for my Android project. This custom class puts the user-inputted zip code into the constructor, and would parse that HTML. It works in an asynchronous thread from my main thread. Since there is no right way to deal with incorrect zip codes, I had check for null
in a particular element, specifically:
if(doc.select("div.columns").first().text() == null)
{
((Activity) context).runOnUiThread(new Runnable() {
public void run()
{
Toast toast = Toast.makeText(context, R.string.toast_parse_fail, Toast.LENGTH_LONG);
toast.show();
return;
}
});
}
If that particular element is null
(meaning that no such data exists for this zip code), it would create a toast to the user. As to why try
wouldn't work in this case, it is because JSoup and Java doesn't know whether the parse failed or not, since the web page still loads fine; only, there is no data, which would crash the app from a NullPointerException
from the code following it.
Despite my Toast
exception handling using .runOnUiThread
, my app would still crash. Is there any particular methods that would cancel the operations that follow my null
-checking method? I know I am crashing because Toast
is not cancelling my operations, and is preceding to execute the following code which causes my NullPointerExceptions
.
Posted is my full Pollen
constructor.
public Pollen(int zipcode, final Context context)
{
this.context = context;
this.zipcode = zipcode;
Document doc;
try
{
// pass address to Wunderground's website using our inputted zipcode
doc = Jsoup.connect("http://www.wunderground.com/DisplayPollen.asp?Zipcode=" + this.zipcode).get();
if(doc.select("div.columns").first().text() == null)
{
((Activity) context).runOnUiThread(new Runnable() {
public void run()
{
Toast toast = Toast.makeText(context, R.string.toast_parse_fail, Toast.LENGTH_LONG);
toast.show();
return;
}
});
}
// get "location" from XML
Element location = doc.select("div.columns").first();
this.location = location.text();
// get "pollen type" from XML
Element pollenType = doc.select("div.panel h3").first();
this.pollenType = pollenType.text();
SimpleDateFormat format = new SimpleDateFormat("EEE MMMM dd, yyyy");
// add the four items of pollen and dates
// to its respective list
for(int i = 0; i < 4; i++)
{
Element dates = doc.select("td.text-center.even-four").get(i);
Element levels = doc.select("td.levels").get(i);
try
{
pollenMap.put(format.parse(dates.text()), levels.text());
}
catch (ParseException e)
{
((Activity) context).runOnUiThread(new Runnable() {
public void run()
{
Toast toast = Toast.makeText(context, R.string.toast_parse_fail, Toast.LENGTH_LONG);
toast.show();
return;
}
});
}
}
}
catch (IOException e)
{
((Activity) context).runOnUiThread(new Runnable() {
public void run()
{
Toast toast = Toast.makeText(context, R.string.toast_parse_fail, Toast.LENGTH_LONG);
toast.show();
return;
}
});
}
}
tl;dr I still want the Toast
to show - but I want on-Toast, to cancel all operations that follow it, since I know that if this particular Toast
shows, if the code following it executes, it would crash the app.