简体   繁体   English

尝试解析XML时Android App崩溃

[英]Android App crashing when trying to parse XML

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. 我正在尝试使用PullParser解析BBC新闻提要,但由于NullPointerExeception ,它在某些情况下崩溃了,我无法弄清原因。

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() 编辑:我应该一直在使用nextText()而不是getText()

Below is the PullParser code 以下是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;
    }

Here is the AsyncTask code: 这是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();
}



 }

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
if(!parser.getText().trim().contains("BBC News -"))

This has at least three potential causes for a NullPointerException : 这至少有三个导致NullPointerException潜在原因:

  1. parser is null . parsernull

  2. getText() returns null getText()返回null

  3. trim() returns null trim()返回null

You initialize parser with XmlPullParserFactory.newInstance().newPullParser() , which probably is guaranteed to return a non-null reference. 您可以使用XmlPullParserFactory.newInstance().newPullParser()初始化parser ,这可以保证返回非空引用。 Assuming that getText() returns a String , 3 is impossible. 假设getText()返回String ,则3是不可能的。 That leaves the first two. 剩下前两个。 This leaves 2 as the most reasonable suspect. 这使2为最合理的嫌疑人。

Note that you should still check 1 and 3, just to be safe. 请注意,为了安全起见,您仍应检查1和3。 You can do this by breaking the if condition into separate statements in order to check each return value. 您可以通过将if条件分成单独的语句来执行此操作,以检查每个返回值。

Once you find where the null value is coming from, you will need to figure out why it is null when you expect otherwise. 一旦找到了null值的来源,您将需要弄清楚为什么null值会为null

Addendum: 附录:

From the documentation for XmlPullParser : XmlPullParser的文档中:

The method next() advances the parser to the next event. 方法next()将解析器前进到下一个事件。 The int value returned from next determines the current parser state and is identical to the value returned from following calls to getEventType (). 从next返回的int值确定当前解析器状态,并且与从随后对getEventType()的调用返回的值相同。

Th[e] following event types are seen by next() next()可查看以下事件类型

START_TAG An XML start tag was read. START_TAG已读取XML开始标签。

TEXT Text content was read; TEXT读取了文本内容; the text content can be retrieved using the getText() method. 可以使用getText()方法检索文本内容。 (when in validating mode next() will not report ignorable whitespace, use nextToken() instead) (在验证模式下,next()不会报告可忽略的空格,请改用nextToken())

END_TAG An end tag was read END_TAG已读取结束标签

END_DOCUMENT No more events are available END_DOCUMENT没有更多活动可用

So it seems that you need to call next() again before you can call getText() to get the text inside the tag. 因此,似乎需要再次调用next()才能调用getText()来获取标记内的文本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 尝试扫描条形码时 Android 应用程序崩溃 - Android app crashing when trying to scan barcode Android Studio - 当 TextView 位于自定义 xml 文件时尝试使用代码更改它的属性时,应用程序崩溃 - Android Studio - App crashing when trying to change a TextView properties with code when it's located at a custom xml file 尝试使用Volley解析Json对象时,Android应用程序崩溃 - Android App Crashing While Trying To Parse Json Object Using Volley 尝试使用SAXParser在Android应用中解析XML - Trying to parse XML in Android app with SAXParser 尝试创建XML FrameLayout,Android应用不断崩溃 - Trying to create xml framelayout, android app keeps crashing Android:尝试将API中的数据加载到列表视图时应用崩溃 - Android: App crashing when trying to load Data from API into a listview 尝试从文件读取数据时,Android应用不断崩溃 - Android app keeps crashing when trying to read data from file 尝试将inputstream转换为字符串时,android应用程序崩溃 - android app crashing when trying to convert inputstream to string 尝试从Firebase获取数据时Android应用程序崩溃 - Android app crashing when trying to get data from Firebase 尝试在 android 5.0 上使用 RecyclerView 时应用程序崩溃 - App crashing when trying to use RecyclerView on android 5.0
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM