我正在使用 LWUIT ResrouceEditor(最新的 SVN 代码修订版 1513)来生成 UI 状态机。
当用户使用当前表单上的按钮调用长时间运行的命令时,我想显示等待屏幕。我相信在链接按钮上的命令时可以使用异步选项。我已经设置了一个表单,其中我有一个应该调用异步命令的按钮。在该按钮的命令选择中,我已将操作设置为显示等待屏幕表单并将命令标记为异步。但是,当我使用异步选项时,代码会显示等待屏幕,但之后会引发 NullPointerException。
根据我的理解,一旦您将命令标记为异步,它将从您可以处理其处理的不同线程调用以下方法。
protected void asyncCommandProcess(Command cmd, ActionEvent sourceEvent);
protected void postAsyncCommand(Command cmd, ActionEvent sourceEvent);
然而,这个方法没有被调用,它会抛出一个 NullPointerException。
当我查看 LWUIT 代码时,在 UIBuilder.java(lineno.2278) 中,我看到它为异步命令构造了新线程,如下所示:
new Thread(new FormListener(currentAction, currentActionEvent, f)).start();
但是当通过 Debugger 运行它时,我看到 currentAction 和 currentActionEvent 始终为空。因此,当 FormListener 线程开始运行时,它永远不会调用上述两种异步命令处理方法。请查看 UIBuilder.java 中的 run() 方法列表(第 2178 行)
public void run() {
if(currentAction != null) {
if(Display.getInstance().isEdt()) {
postAsyncCommand(currentAction, currentActionEvent);
} else {
asyncCommandProcess(currentAction, currentActionEvent);
// wait for the destination form to appear before moving back into the LWUIT thread
waitForForm(destForm);
}
} else {
if(Display.getInstance().isEdt()) {
if(Display.getInstance().getCurrent() != null) {
exitForm(Display.getInstance().getCurrent());
}
Form f = (Form)createContainer(fetchResourceFile(), nextForm);
beforeShow(f);
f.show();
postShow(f);
} else {
if(processBackground(destForm)) {
waitForForm(destForm);
}
}
}
}
在上述方法中,由于 currentAction 为 null,它总是进入 else 语句,并且由于 nextForm 也是 null,它会导致 NullPointerException。
进一步查看 UIBuilder.java 代码,我注意到导致 NullPointer 异常的原因。似乎在创建 FormListner 时,它被传递了 currentAction 和 currentActionEvent,但是它们当时为空。相反,代码应更改如下(从第 2264 行开始):
if(action.startsWith("@")) {
action = action.substring(1);
Form currentForm = Display.getInstance().getCurrent();
if(currentForm != null) {
exitForm(currentForm);
}
Form f = (Form)createContainer(fetchResourceFile(), action);
beforeShow(f);
/* Replace following with next lines for fixing asynchronous command
if(Display.getInstance().getCurrent().getBackCommand() == cmd) {
f.showBack();
} else {
f.show();
}
postShow(f);
new Thread(new FormListener(currentAction, currentActionEvent, f)).start();
*/
new Thread(new FormListener(cmd, evt, f)).start();
return;
}
lwuit开发团队可以看看上面的代码,审查并修复它。在我进行上述更改后,调用了异步命令处理方法。
谢谢你。