Reputation: 598
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
Reputation: 83527
if(!parser.getText().trim().contains("BBC News -"))
This has at least three potential causes for a NullPointerException
:
parser
is null
.
getText()
returns null
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