【问题标题】:Android App crashing when trying to parse XML尝试解析 XML 时 Android 应用程序崩溃
【发布时间】:2014-09-27 03:56:30
【问题描述】:

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

【问题讨论】:

  • NewsUtil.java 的第 34 行在哪里?
  • return NewsUtil.NewsItemPullParser.parseNewsItems(in);AsyncTask 代码中。我认为它崩溃了,因为它返回一个空列表,因为解析出了点问题。即使我尝试记录第一个 parser.getText(),我什么也得不到。
  • 这看起来是来自GetNewsAsyncTask.java 的第 34 行。但是错误发生在NewsUtil.java insideparseNewsItems() 的调用的第 34 行。这是哪条线?
  • 哎呀!对不起。这是第一个if 语句中的第一个parser.getText()if(!parser.getText().trim().contains("BBC News -"))

标签: android xml parsing


【解决方案1】:
if(!parser.getText().trim().contains("BBC News -"))

NullPointerException 至少有三个潜在原因:

  1. parsernull

  2. getText() 返回null

  3. trim() 返回null

您使用XmlPullParserFactory.newInstance().newPullParser() 初始化parser,这可能保证返回非空引用。假设getText() 返回String,3 是不可能的。剩下前两个。这使得 2 成为最合理的嫌疑人。

请注意,为了安全起见,您仍应检查 1 和 3。您可以通过将if 条件分解为单独的语句来执行此操作,以检查每个返回值。

一旦您找到了 null 值的来源,您将需要弄清楚为什么它是 null,而不是预期。

附录:

来自XmlPullParser 的文档:

方法 next() 将解析器推进到下一个事件。从 next 返回的 int 值确定当前解析器状态,并且与从以下对 getEventType () 的调用返回的值相同。

next() 可以看到 Th[e] 以下事件类型

START_TAG 读取了一个 XML 开始标记。

文本 文本内容被阅读;可以使用 getText() 方法检索文本内容。 (在验证模式下 next() 不会报告可忽略的空格,请使用 nextToken() 代替)

END_TAG 读取了结束标签

END_DOCUMENT 没有更多活动可用

所以看来你需要再次调用next()才能调用getText()来获取标签内的文本。

【讨论】:

  • 经过测试,getText() 为空。当我还测试getName() 时,我得到了我正在寻找的正确标签,即&lt;title&gt; XML 标签看起来像:&lt;title&gt;BBC News - Home&lt;/title&gt; 所以getText() 应该是获取该文本的正确方法吗?跨度>
  • 等等!!!我又看了一遍文档,不是getText()。应该是nextText() 现在这很令人沮丧。
猜你喜欢
  • 1970-01-01
  • 2013-02-06
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 2012-11-26
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多