Android SAXParser工作在2.2.1但不在2.2

时间:2011-06-20 21:08:36

标签: android xml saxparser

我有这些类和函数:

从XML读取偏好

private void readPreferences(InputSource is) {
PrefsFetcher pf = new PrefsFetcher();
prefs = pf.getPreferences(is);
if (prefs == null) {
    Log.d(Constants.TAG, "prefs == null");
} 
// save to DB
savePreferences();
}

偏好设定器

public class PrefsFetcher {

public ArrayList<Preferences> getPreferences(InputSource is) {

    ArrayList<Preferences> prefs = null;

    try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();
        XMLReader xmlReader = saxParser.getXMLReader();

        PrefsHandler handler = new PrefsHandler();
        xmlReader.setContentHandler(handler);
        Log.d(Constants.TAG, "Parsing XML");
        xmlReader.parse(is);
        prefs = handler.getPreferences();

    } catch (Exception e) {
        e.printStackTrace();
    }
    return prefs;
}

}

偏好处理程序

public class PrefsHandler extends DefaultHandler {

private static final String PREFERENCES = "preferences";
private static final String DNI = "id";
private static final String FREQUENCY = "interval";
private static final String PHONE_NUMBER = "phoneNumber";
private static final String SERVER_ADDRESS = "serverAddress";
private static final String SERVER_PORT = "serverPort";
private static final String SERVER_PREF_ADDRESS = "prefAddress";
private static final String SERVER_PREF_PORT = "prefPort";

private boolean idChars;
private boolean frequencyChars;
private boolean phoneNumberChars;
private boolean serverAddressChars;
private boolean serverPortChars;
private boolean prefAddressChars;
private boolean prefPortChars;

boolean startPreferences;

private int numPrefs;
private Preferences pref;
private final ArrayList<Preferences> prefs;

public PrefsHandler(){
    this.prefs = new ArrayList<Preferences>();
}

@Override
public void startDocument(){
}

@Override
public void startElement(String uri, String localName, String qName, Attributes atts) {

    //Log.d(Constants.TAG, "XML localName: " + localName + " qName: " + qName);

    if (localName.equals(PREFERENCES)) {
        this.startPreferences = true;
        this.pref = new Preferences();
    }
    if (this.startPreferences){
        if (localName.equals(FREQUENCY)) {
            this.frequencyChars = true;
        } else if (localName.equals(PHONE_NUMBER)) {
            this.phoneNumberChars = true;
        } else if (localName.equals(DNI)) {
            this.idChars = true;
        } else if (localName.equals(SERVER_ADDRESS)) {
            this.serverAddressChars = true;
        } else if (localName.equals(SERVER_PORT)) {
            this.serverPortChars = true;
        } else if (localName.equals(SERVER_PREF_ADDRESS)) {
            this.prefAddressChars = true;
        } else if (localName.equals(SERVER_PREF_PORT)) {
            this.prefPortChars = true;
        }
    }
}

@Override
public void endDocument(){}

@Override
public void endElement(String uri, String localName, String qName) {
    if (localName.equals(PREFERENCES)){
        this.startPreferences = false;
        this.numPrefs++;
        this.prefs.add(this.pref);
    }
    if (this.startPreferences){
        if (localName.equals(FREQUENCY)) {
            this.frequencyChars = false;
        } else if (localName.equals(PHONE_NUMBER)) {
            this.phoneNumberChars = false;
        } else if (localName.equals(DNI)) {
            this.idChars = false;
        } else if (localName.equals(SERVER_ADDRESS)) {
            this.serverAddressChars = false;
        } else if (localName.equals(SERVER_PORT)) {
            this.serverPortChars = false;
        } else if (localName.equals(SERVER_PREF_ADDRESS)) {
            this.prefAddressChars = false;
        } else if (localName.equals(SERVER_PREF_PORT)) {
            this.prefPortChars = false;
        }
    }
}

@Override
public void characters(char [] ch, int start, int length) {
    String chString = "";
    if (ch != null) {
        chString = new String (ch, start, length);
    }

    if (this.startPreferences) {
        //Log.d(Constants.TAG, "chString: " + chString);
        if (this.idChars) {
            this.pref.setId(chString);
        } else if (this.frequencyChars) {
            this.pref.setFrequency(chString);
        } else if (this.phoneNumberChars) {
            this.pref.setPhoneNumber(chString);
        } else if (this.serverAddressChars) {
            this.pref.setServerAddress(chString);
        } else if (this.serverPortChars) {
            this.pref.setServerPort(chString);
        } else if (this.prefAddressChars) {
            this.pref.setPrefAddress(chString);
        } else if (this.prefPortChars) {
            this.pref.setPrefPort(chString);
        }
    }
}

public ArrayList<Preferences> getPreferences(){
    Log.d(Constants.TAG, "prefs length: " + prefs.size());
    return this.prefs;
}

public String getAttributeValue(String attName, Attributes atts){
    String result = null;
    for (int i = 0; i < atts.getLength(); i++){
        String thisAtt = atts.getLocalName(i);
        if (attName.equals(thisAtt)){
            result = atts.getValue(i);
            break;
        }
    }
    return result;
}

}

如果我在模拟器或带有2.2.1的HTC Wildfire上运行此代码,它运行良好,我可以将这些首选项保存在数据库中。但是,当我在带有2.2的三星Galaxy S上运行它时,我确实在readPreferences函数中返回一个空值。

它是2.2上的错误还是我做错了什么?

感谢您的帮助,

1 个答案:

答案 0 :(得分:0)

  

它是2.2上的错误还是我做错了什么?

我不知道2.2中是否存在错误,但您至少做过一件事。

解析器可以多次调用characters方法,在每次调用时部分提供字符。您的characters方法只有在您运气好的情况下才有效,并且只能召唤一次。

要正确处理SAX中的字符,您需要(对于需要收集字符的每个标记)在startElement方法中初始化缓冲区,在characters方法中将字符收集到缓冲区中,并使用endElement方法获得结果。