1

I have come across many posts regarding the issue of AsycTask not running and wanted to confirm if that is indeed the issue with my implementation. Should I try to implement this method instead?

I call the following method in my onCreate method using new GetRoutes().execute("test");. The information provided by the AsyncTask is used to build a ListView of parsed information. However, this method does not update the "values" array as it should.

private class GetRoutes extends AsyncTask<String, Void, String[]> {
    @Override
    protected String[] doInBackground(String... urls) {
      List<String> in = new ArrayList<String>();
          try{
            RouteReader route = new RouteReader();
            in = route.parse(new URL(RouteReader.URI).openStream());
        } catch(IOException iox){
            in.add("Major poopoo");
            //in.add(getResources().getString(R.string.loading_error));
        } catch(ArrayIndexOutOfBoundsException aiob){
            in.add("Minor poopoo");
            //in.add(getResources().getString(R.string.loading_error));
        } catch(NullPointerException npe){
            in.add("Small poopoo");
            //in.add(getResources().getString(R.string.loading_error));
        } catch (XmlPullParserException e) {
            in.add(getResources().getString(R.string.loading_error));
        }
      return in.toArray(new String[in.size()]);
    }

    @Override
    protected void onPostExecute(String[] result) {
      values = result;
    }
}

The RouteReader class is as follows:

public class RouteReader {
    private XmlPullParser parser;

    public final static String URI = 
            "http://webservices.nextbus.com/service/publicXMLFeed?command=routeList&a=ttc";

    public RouteReader(){
         parser = Xml.newPullParser();
    }

     public List<String> parse(InputStream in) throws XmlPullParserException, IOException {
            try {
                parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
                parser.setInput(in, null);
                parser.nextTag();
                return readFeed(parser);
            } finally {
                in.close();
            }
     }

     private List<String> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
            List<String> entries = new ArrayList<String>();

            parser.require(XmlPullParser.START_TAG, null, "body");
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                String name = parser.getName();
                if (name.equals("route")) {
                    entries.add(parser.getAttributeValue(null, "id"));
                    System.out.println(parser.getAttributeValue(null, "id"));
                }
            }  
            return entries;
        }
    }

Could you please help me in pinpointing the issue with this implementation?

Community
  • 1
  • 1
osama
  • 622
  • 2
  • 10
  • 19
  • 1
    Is it possible that you try to access the value of `values` directly after calling `new GetRoutes().execute("test");`? I.e. not waiting for the async result set by `onPostExecute` (the code that uses the result must be triggered from `onPostExecute`) – zapl Jan 02 '14 at 20:56
  • @zapl Yes, that turned out to be the error. Thanks! – osama Jan 02 '14 at 21:25

1 Answers1

2

if your doInBackground() method is not called, try calling your task like this, this is a known issue:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    new GetRoutes().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "test");
else
    new GetRoutes().execute("test");

and add this to the top of the method that calls the asynk task, (eclipse will ask you to so just in case ..)

@SuppressLint("NewApi")

SOLUTION UPDATE:

as I saw you are implementing the adapter right after the call of the asynktask, but with this beeing asynchronous, you MUST wait for the adapter until the task has finished, generally this is beeing made on the onPostExecute() method, so replace your lines

final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                    R.layout.list_item, android.R.id.text1, values);

list.setAdapter(adapter);

inside onPostExecute(), and retry

TootsieRockNRoll
  • 3,218
  • 2
  • 25
  • 50
  • it all seems okey, try cleaning your project – TootsieRockNRoll Jan 02 '14 at 20:48
  • It seems that the values array still does not update. – osama Jan 02 '14 at 20:50
  • are you sure there is no exception out there ? – TootsieRockNRoll Jan 02 '14 at 20:51
  • I believe that I am catching the relevant Exceptions (and they should still update the array). [However, you may view my LogCat to verify.](http://pastebin.com/VEy922W1) – osama Jan 02 '14 at 20:54
  • 1
    add an e.printStackTrace() on all your catch clauses to really be sure if there is any error, – TootsieRockNRoll Jan 02 '14 at 20:56
  • Thanks for the tip. [Could this possibly indicate a problem with my parsing?](http://pastebin.com/BnDM023t) – osama Jan 02 '14 at 21:01
  • [I have updated my GetRoutes method](http://pastebin.com/uGV8Jca2) and it still does not update the array. – osama Jan 02 '14 at 21:03
  • 1
    there is a NPE . . 01-02 16:00:10.779: W/System.err(1361): java.lang.NullPointerException 01-02 16:00:10.779: W/System.err(1361): at com.android.internal.os.LoggingPrintStream.println(LoggingPrintStream.java:298) – TootsieRockNRoll Jan 02 '14 at 21:04
  • 1
    hoooold on for a sec, show the code of the asynktask call, with the implementation of the adapter for the listview, because it is asynchronous, so the adapter MUST be called after doInBackground, ie onPostExecute – TootsieRockNRoll Jan 02 '14 at 21:05
  • [This is the code you have requested](http://pastebin.com/xte070mB), should I move the adapter? – osama Jan 02 '14 at 21:13