尝试解析XML时Android App崩溃

时间:2014-09-27 03:56:31

标签: android xml parsing

我正在尝试使用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

1 个答案:

答案 0 :(得分:1)

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

NullPointerException至少有三个潜在原因:

  1. parsernull

  2. getText()返回null

  3. trim()返回null

  4. 使用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()以获取代码中的文字。