[英]Android App crashing when trying to parse XML
我正在嘗試使用PullParser
解析BBC新聞提要,但由於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
if(!parser.getText().trim().contains("BBC News -"))
這至少有三個導致NullPointerException
潛在原因:
parser
為null
。
getText()
返回null
trim()
返回null
您可以使用XmlPullParserFactory.newInstance().newPullParser()
初始化parser
,這可以保證返回非空引用。 假設getText()
返回String
,則3是不可能的。 剩下前兩個。 這使2為最合理的嫌疑人。
請注意,為了安全起見,您仍應檢查1和3。 您可以通過將if
條件分成單獨的語句來執行此操作,以檢查每個返回值。
一旦找到了null
值的來源,您將需要弄清楚為什么null
值會為null
。
附錄:
從XmlPullParser
的文檔中:
方法next()將解析器前進到下一個事件。 從next返回的int值確定當前解析器狀態,並且與從隨后對getEventType()的調用返回的值相同。
next()可查看以下事件類型
START_TAG已讀取XML開始標簽。
TEXT讀取了文本內容; 可以使用getText()方法檢索文本內容。 (在驗證模式下,next()不會報告可忽略的空格,請改用nextToken())
END_TAG已讀取結束標簽
END_DOCUMENT沒有更多活動可用
因此,似乎需要再次調用next()
才能調用getText()
來獲取標記內的文本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.