Different behavior of XmlPullParser.getInputEncoding() on API11+ and pre-API11 versions of Android

前端 未结 2 777
无人及你
无人及你 2021-01-16 08:59

I am developing a new feature for my android app to enable data backup and restore. I am using XML files to backup data. This is a piece of code that sets encoding for an ou

2条回答
  •  囚心锁ツ
    2021-01-16 09:59

    After some more trial and error, I've finally managed to figure out what's going on. So despite the fact that the documentation says:

    Historically Android has had two implementations of this interface: KXmlParser via XmlPullParserFactory.newPullParser(). ExpatPullParser, via Xml.newPullParser().

    Either choice is fine. The example in this section uses ExpatPullParser, via Xml.newPullParser().

    The reality is, that on older APIs, such as 2.3.3 Xml.newPullParser() returns ExpatPullParser object. While on Ice Cream Sandwich and up it returns KXmlParser object. And as we can see from this blog post, android developers knew about this since December 2011:

    In Ice Cream Sandwich we changed Xml.newPullParser() to return a KxmlParser and deleted our ExpatPullParser class.

    ...but never bothered to update the official documentation.

    So how do you retrieve KXmlParser object on APIs before Ice Cream Sandwich? Simple:

    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    XmlPullParser parser = factory.newPullParser();
    

    ...in fact this works on all versions of android, new and old. Then you supply a FileInputStream to your parser's setInput() method, leaving default encoding null:

    FileInputStream stream = null;
    stream = new FileInputStream(file);
    parser.setInput(stream, null);
    

    After this, on APIs 11 and higher you can call parser.getInputEncoding() right away and it will return the correct encoding. But on pre-API11 versions, it will return null unless you call parser.next() first, as @Esailija correctly pointed out in his answer. Interestingly enough, on API11+ calling next() doesn't have any negative effect whatsoever, so you may safely use this code on all versions:

    parser.next();
    String encoding = parser.getInputEncoding();
    

    And this will correctly return "UTF-8".

提交回复
热议问题