WeVie
WeVie

Reputation: 598

Android App crashing when trying to parse XML

I am trying to parse a BBC news feed with PullParser but it is crashing for some due to a NullPointerExeception and I cannot figure out why.

There is also two title tags before the actual first title tag that I want to parse and one description tag before the one I one to parse and I am not totally sure I am handling that correctly but even if I am not, I don't think that is causing the issue, but I could be wrong.

Thanks to anyone taking a look at this!

EDIT: I should have been using nextText() rather than getText()

Below is the PullParser code

 static public class NewsItemPullParser{

    static ArrayList<NewsItems> parseNewsItems(InputStream in) throws XmlPullParserException, IOException{
        XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
        parser.setInput(in, "UTF-8");
        NewsItems newsItem = null;
        ArrayList<NewsItems> newsList = new ArrayList<NewsItems>();
        int event = parser.getEventType();

        while(event != XmlPullParser.END_DOCUMENT){

            switch(event){
            case XmlPullParser.START_TAG:

                if(parser.getName().equals("title")){
                    if(!parser.getText().trim().contains("BBC News -")){
                        newsItem = new NewsItems();
                        newsItem.setTitle(parser.getText().trim());
                        Log.d("Title", parser.getText().trim());
                    }
                }else if(parser.getName().equals("description")){
                    if(!parser.getText().trim().contains("The latest stories")){
                        newsItem.setDescritpion(parser.getText().trim());
                        Log.d("description", parser.getText().trim());
                    }
                }else if(parser.getName().equals("pubDate")){
                    newsItem.setPubDate(parser.getText().trim());
                }else if(parser.getName().equals("media:thumbnail")){
                    if(parser.getAttributeValue(null, "width").equals("66")){
                        newsItem.setThmnSmall(parser.getAttributeValue(null, "url").trim());
                        Log.d("small thumbnail", parser.getAttributeValue(null, "url").trim());
                    }   
                }else if(parser.getName().equals("media:thumbnail")){
                    if(parser.getAttributeValue(null, "width").equals("144")){
                        newsItem.setThmnLarge(parser.getAttributeValue(null, "url").trim());
                        Log.d("large thumbnail", parser.getAttributeValue(null, "url").trim());
                    }       
                }

                break;
            case XmlPullParser.END_TAG:
                if(parser.getName().equals("title")){
                    newsList.add(newsItem);
                    newsItem = null;
                }

            default:
                break;
            }
            event = parser.next();

        }
        return newsList;
    }

Here is the AsyncTask code:

 public class GetNewsAsyncTask extends AsyncTask<String, Void,  ArrayList<NewsItems>> {
NewsActivity activity;

public GetNewsAsyncTask(NewsActivity activity){
    this.activity = activity;

}

@Override
protected ArrayList<NewsItems> doInBackground(String... params) {

    try {
        URL url = new URL(params[0]);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("GET");
        con.connect();
        int statusCode = con.getResponseCode();
        if(statusCode == HttpURLConnection.HTTP_OK){
            InputStream in = con.getInputStream();
            return NewsUtil.NewsItemPullParser.parseNewsItems(in);
        }
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

        return null;
}

@Override
protected void onPreExecute() {
    // TODO Auto-generated method stub
    super.onPreExecute();
    //NewsActivity.pd.show();
}

@Override
protected void onPostExecute(ArrayList<NewsItems> result) {
    super.onPostExecute(result);
    //NewsActivity.pd.dismiss();
}



 }

Here is the log error:

 09-27 03:36:25.594: E/AndroidRuntime(1720): FATAL EXCEPTION: AsyncTask #1
 09-27 03:36:25.594: E/AndroidRuntime(1720): java.lang.RuntimeException: An error occured while executing doInBackground()
 09-27 03:36:25.594: E/AndroidRuntime(1720): at     android.os.AsyncTask$3.done(AsyncTask.java:299)
 09-27 03:36:25.594: E/AndroidRuntime(1720): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at java.lang.Thread.run(Thread.java:856)
 09-27 03:36:25.594: E/AndroidRuntime(1720): Caused by: java.lang.NullPointerException
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at com.example.bbcnewsapp.NewsUtil$NewsItemPullParser.parseNewsItems(NewsUtil.java:34)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at com.example.bbcnewsapp.GetNewsAsyncTask.doInBackground(GetNewsAsyncTask.java:34)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at com.example.bbcnewsapp.GetNewsAsyncTask.doInBackground(GetNewsAsyncTask.java:1)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
 09-27 03:36:25.594: E/AndroidRuntime(1720):    ... 4 more
 09-27 03:36:27.726: I/Process(1720): Sending signal. PID: 1720 SIG: 9

Upvotes: 0

Views: 658

Answers (1)

Code-Apprentice
Code-Apprentice

Reputation: 83527

if(!parser.getText().trim().contains("BBC News -"))

This has at least three potential causes for a NullPointerException:

  1. parser is null.

  2. getText() returns null

  3. trim() returns null

You initialize parser with XmlPullParserFactory.newInstance().newPullParser(), which probably is guaranteed to return a non-null reference. Assuming that getText() returns a String, 3 is impossible. That leaves the first two. This leaves 2 as the most reasonable suspect.

Note that you should still check 1 and 3, just to be safe. You can do this by breaking the if condition into separate statements in order to check each return value.

Once you find where the null value is coming from, you will need to figure out why it is null when you expect otherwise.

Addendum:

From the documentation for XmlPullParser:

The method next() advances the parser to the next event. The int value returned from next determines the current parser state and is identical to the value returned from following calls to getEventType ().

Th[e] following event types are seen by next()

START_TAG An XML start tag was read.

TEXT Text content was read; the text content can be retrieved using the getText() method. (when in validating mode next() will not report ignorable whitespace, use nextToken() instead)

END_TAG An end tag was read

END_DOCUMENT No more events are available

So it seems that you need to call next() again before you can call getText() to get the text inside the tag.

Upvotes: 1

Related Questions