Note that there are some explanatory texts on larger screens.

plurals
  1. POJsoup Issues in Android AsyncTask
    primarykey
    data
    text
    <p><strong>Summary:</strong> My Jsoup parser works perfectly on its own, but fails to gather any values once copy-pasted into one of my Android application's AsyncTask task classes. The 2d array is returned filled with nothing but nulls.</p> <p><strong>Long version:</strong> I have been working on an application that uses page-scraping via Jsoup to pull and display content from various blogs. I have written a few parsers so far, and all seem to work as expected. Unfortunately, my most recent parser (written for nyc-shows.brooklynvegan.com), has been having issues. </p> <p>Here is the parser method itself, invoked by a main method with print statements added. Run this yourself. It works (not perfectly, but it works). </p> <pre><code>import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class Main { static String TAG_EVENT = "li.ds-entry"; static String TAG_TITLE = ".ds-entry-title"; static String TAG_LOCATION = ".location"; static String TAG_DATE_AND_TIME = ".ds-date"; static String TAG_TICKET_URL = ".ds-buy-tickets"; static String FEED_URL = "http://nyc-shows.brooklynvegan.com/"; public static void main(String[] args) throws IOException { String values[][] = new String[50][6]; values = getFeedItems(); for (int i=0; i&lt;values.length; i++) { for (int j=0; j&lt;6; j++) { System.out.println(values[i][j]); } System.out.println("-----------------"); } } public static String[][] getFeedItems() throws IOException { Document doc = null; String values[][] = new String[50][6]; try{ doc = Jsoup.connect(FEED_URL).timeout(0).get(); Elements events = doc.select(TAG_EVENT); String delimSpace = "[ ]"; int i = 0; for (Element event : events) { //Set event title Element title = event.select(TAG_TITLE).first(); String titleString = title.text(); if (title != null) { boolean isFake = checkFake(titleString); if (!isFake) { values[i][0] = titleString; } else { continue; } } //Set event date and time i guess Element dateAndTime = event.select(TAG_DATE_AND_TIME).first(); if (dateAndTime != null) { String[] dateAndTimeTokens = dateAndTime.text().split(delimSpace); String date = dateAndTimeTokens[1]; String time = dateAndTimeTokens[3]; values[i][1] = date; values[i][2] = time; } //Set price (tbd) values[i][3] = "See Ticket"; //Set location Element location = event.select(TAG_LOCATION).first(); if (location != null) { values[i][4] = location.text(); } //Set ticket urls Element ticketContainer = event.select(TAG_TICKET_URL).first(); if (ticketContainer != null) { String ticket = ticketContainer.select("a").attr("href"); values[i][5] = ticket; } else { values[i][3] = "Free"; } i++; } //End of event loop } //End of try clause catch (IOException e) { e.printStackTrace(); } return values; } public static boolean checkFake(String s) { boolean isFake = false; String[] days = {"Today", "Tomorrow", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; for (int i=0; i&lt;days.length; i++) { if (s.contains(days[i])) { isFake = true; return isFake; } } return isFake; } } </code></pre> <p>Now, here is the same exact method transported into an AsyncTask to be run in the background by my application while a loading screen is displayed.</p> <pre><code>package com.example.nylist; import java.io.IOException; import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class BVParser extends AsyncTask&lt;Void, Void, String[][]&gt; { static String TAG_EVENT = "li.ds-entry"; static String TAG_TITLE = ".ds-entry-title"; static String TAG_LOCATION = ".location"; static String TAG_DATE_AND_TIME = ".ds-date"; static String TAG_TICKET_URL = ".ds-buy-tickets"; static String FEED_URL = "http://nyc-shows.brooklynvegan.com/"; Context context; Activity activity; public BVParser(Activity context) { this.context = context.getApplicationContext(); this.activity = context; } @Override protected void onPreExecute() { super.onPreExecute(); Toast.makeText(context, "Fetching...", Toast.LENGTH_LONG).show(); } @Override protected String[][] doInBackground(Void... param) { String values[][] = new String[50][6]; try { values = getFeedItems(); } catch (IOException e) { Log.d("ASSERT", "Exception occured during doInBackground", e); e.printStackTrace(); } Log.d("ASSERT", ("values successfully returned by doInBackground, first title is: "+values[0][0])); return values; } protected void onPostExecute(String[][] result) { super.onPostExecute(result); int eventCount = result.length; Log.d("ASSERT", ("event count in onPostExecute is: "+eventCount)); ListRow[] listrow_data = new ListRow[eventCount]; ListRow temp; for (int i=0; i&lt;eventCount; i++) { if (result[i] != null) { temp = new ListRow(context, result[i][0], result[i][1], result[i][2], result[i][3], result[i][4], result[i][5], i); listrow_data[i] = temp; } } ((EventList) activity).setList(listrow_data); } public String[][] getFeedItems() throws IOException { Document doc = null; String values[][] = new String[50][6]; int i = 0; try{ Log.d("ASSERT","Made it to try block"); doc = Jsoup.connect(FEED_URL).timeout(0).get(); Elements events = doc.select(TAG_EVENT); Log.d("ASSERT","printing events, whatever it is: "+events); String delimSpace = "[ ]"; //******THIS LOOP NEVER BEGINS*****// for (Element event : events) { Log.d("ASSERT","Made it to getFeedItems's main for loop"); //Set event title Element title = event.select(TAG_TITLE).first(); String titleString = title.text(); Log.d("ASSERT","This title is: "+titleString); boolean isFake = checkFake(titleString); if (!isFake) { values[i][0] = titleString; } else { continue; } //Set event date and time i guess Element dateAndTime = event.select(TAG_DATE_AND_TIME).first(); if (dateAndTime != null) { String[] dateAndTimeTokens = dateAndTime.text().split(delimSpace); String date = dateAndTimeTokens[1]; String time = dateAndTimeTokens[3]; values[i][1] = date; values[i][2] = time; } //Set price values[i][3] = "See Ticket"; //Set location Element location = event.select(TAG_LOCATION).first(); if (location != null) { values[i][4] = location.text(); } //Set ticket urls Element ticketContainer = event.select(TAG_TICKET_URL).first(); if (ticketContainer != null) { String ticket = ticketContainer.select("a").attr("href"); values[i][5] = ticket; } else { values[i][3] = "Free"; } i++; } //End of event loop } //End of try clause catch (IOException e) { Log.d("ASSERT","Exception during getFeedItems"); e.printStackTrace(); } Log.d("ASSERT","The first title in getFeedItems before returning is: "+values[0][0]); return values; } private static boolean checkFake(String s) { boolean isFake = false; String[] days = {"Today", "Tomorrow", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; for (int i=0; i&lt;days.length; i++) { if (s.contains(days[i])) { isFake = true; return isFake; } } return isFake; } } </code></pre> <p><strong>Debugging Attempts:</strong> I added log statements throughout the code in order to debug the problem. If you run this, you will see that the problem seems to occur somewhere within getFeedItems() itself, specifically within the "try" block. Although the log statement at the beginning of the try statement appears, the for loop that runs through <code>events</code> isn't running at all, because the log statement at it's beginning never prints. </p> <p><strong>Question:</strong> Can someone explain why the loop through <code>events</code> doesn't begin? Is <code>events</code> null, and if so, why? Why is there a discrepancy between the method running on it's own and the method running within my AsyncTask? I have been tearing my hair out. The logic in this parser is almost identical to the logic in the (working) others that I have written, and yet this is returning a 2d array with nothing but nulls. I have trouble even beginning to understand where the logic error might be, and yet I just can't seem to find the typo.</p> <p><strong>PS:</strong> If comparing this with my other parser would help, let me know and I'll post the source. Thanks in advance.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload