我正在尝试使用PullParser
解析BBC新闻Feed但由于NullPointerExeception
而导致某些人崩溃,我无法弄清楚原因。
在我要解析的实际第一个标题标记之前还有两个标题标记,在我要解析的标记之前还有一个描述标记,我不完全确定我正确处理它,但即使我不是,我也是不要以为这会导致问题,但我可能是错的。
感谢有人看看这个!
编辑:我应该使用nextText()
而不是getText()
以下是PullParser
代码
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;
}
以下是AsyncTask
代码:
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();
}
}
以下是日志错误:
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
答案 0 :(得分:1)
if(!parser.getText().trim().contains("BBC News -"))
NullPointerException
至少有三个潜在原因:
parser
为null
。
getText()
返回null
trim()
返回null
使用parser
初始化XmlPullParserFactory.newInstance().newPullParser()
,可能保证返回非空引用。假设getText()
返回String
,则3是不可能的。这留下了前两个。这使得2是最合理的嫌疑人。
请注意,您仍应检查1和3,以确保安全。您可以通过将if
条件分解为单独的语句来检查每个返回值。
找到null
值的来源后,您需要在需要时找出null
的原因。
<强>附录:强>
来自XmlPullParser
的文档:
方法next()将解析器推进到下一个事件。从next返回的int值确定当前解析器状态,并且与从以下对getEventType()的调用返回的值相同。
下一个()
可以看到以下事件类型。[p]START_TAG 读取了XML开始标记。
TEXT 阅读文字内容;可以使用getText()方法检索文本内容。 (当在验证模式next()不报告可忽略的空格时,请改用nextToken())
END_TAG 读取了结束标记
END_DOCUMENT 没有更多活动可用
因此,您似乎需要再次致电next()
,然后才能致电getText()
以获取代码中的文字。