我们有以下方法来解析XML文件并相应地显示其内容:
@Background
@AfterInject
void parseXMLAndLoadContent() {
try {
URL url = new URL(URI);
xmlParser.setInput((InputStream) url.getContent());
showProgressDialog();
angeboteXML = xmlParser.parse();
if (angeboteXML != null) { // Breakpoint here
if (angeboteXML.backgroundImage != "") {
loadBitmapFromUrl(angeboteXML.backgroundImage);
}
loadAngebote();
} else
throw new Exception();
} catch (Exception exception) {
showToast();
} finally {
dismissProgressDialog();
}
}
正如您所看到的,它应该显示一个进度对话框(用@UiThread
注释的方法),然后调用XML解析器并处理结果。
不幸的是,只有在我调用parse()
之后在上面提到的行中设置断点时,这才有效。不知何故,这会导致某个宽限期,允许解析器处理文档。如果我让它在没有断点的情况下运行,则没有任何反应,即使进度对话框显示也没有,angeboteXML
为空。
由于我不是Android专家 - 为什么会发生这种情况,有什么我可以改进的吗?据我所知,这应该按顺序执行,即在解析器完成解析之后,执行其他所有操作。但这不是这里的情况。
编辑16/05/13 13:21:
在Thread.sleep(1000)
之后添加parse()
会有所帮助,但它似乎更像是一种解决方法,而不是修复方法。
这是方法执行的跟踪日志:
05-16 13:19:26.168: I/AngeboteActivity(6051): Entering [void parseXMLAndLoadContent() ]
05-16 13:19:26.278: I/AngeboteXMLParser(6051): Entering [public de.sample.app.helper.AngeboteXML parse() throws org.xmlpull.v1.XmlPullParserException, java.io.IOException]
05-16 13:19:26.318: I/AngeboteXMLParser(6051): Exiting [public de.sample.app.helper.AngeboteXML parse() throws org.xmlpull.v1.XmlPullParserException, java.io.IOException], duration in ms: 35
05-16 13:19:26.318: I/AngeboteActivity(6051): Exiting [void parseXMLAndLoadContent() ], duration in ms: 147
05-16 13:19:26.318: I/AngeboteActivity(6051): Entering [void loadAngebote() ]
loadAngebote()
是抛出NPE的地方,因为解析器似乎尚未完成。
编辑16/05/13 13:29
这是parse()
方法的实现方式:
public AngeboteXML parse() throws XmlPullParserException, IOException {
this.xml = new AngeboteXML();
int eventType = this.parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG :
this.readStartTag(this.parser.getName());
break;
case XmlPullParser.END_TAG :
this.readEndTag(this.parser.getName());
break;
case XmlPullParser.TEXT :
this.readText(this.parser.getText());
break;
default :
break;
}
this.parser.next();
eventType = this.parser.getEventType();
}
return xml;
}
答案 0 :(得分:1)
实际上,我认为这是一个设计问题。对xmlParser.parse()的调用是您要在后台执行的任务。之前和之后的所有内容都属于另一种触发此任务的方法。
我不知道@Background功能是如何工作的,但是如果你使用http://developer.android.com/reference/android/os/AsyncTask.html,会有一个onProgressUpdate(在这里放showProgressDialog())和一个onPostExecute回调(把dismissProgressDialog()放入这里)。看一下android注释的文档,我建议如下:
@AfterViews
void initXMLParsing() {
showProgressDialog();
parseXMLAndLoadContent();
}
@Background
void parseXMLAndLoadContent() {
try {
// ...
} catch (Exception exception) {
showToast();
} finally {
dismissProgressDialog();
}
}