Я использую LWUIT ResrouceEditor (последняя редакция кода SVN 1513) для генерации конечного автомата пользовательского интерфейса.
Я хочу показать экран ожидания, когда пользователь выполняет длительную команду с помощью кнопки в текущей форме. Я считаю, что могу использовать асинхронную опцию при связывании команды на кнопке. Я настроил форму, в которой у меня есть кнопка, которая должна вызвать асинхронную команду. При выборе команды для этой кнопки я установил действие, чтобы показать форму экрана ожидания, и пометил команду как асинхронную. Однако, когда я использую асинхронную опцию, код показывает экран ожидания, но после этого он генерирует исключение 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();
Но при запуске его через отладчик я вижу, что currentAction и currentActionEvent всегда равны нулю. И, следовательно, когда поток FormListener начинает работать, он никогда не вызывает вышеупомянутые два метода обработки асинхронных команд. Пожалуйста, посмотрите листинг метода run () в UIBuilder.java (строка № 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 взглянуть на приведенный выше код, просмотреть и исправить его. После внесения вышеуказанных изменений были вызваны методы асинхронной обработки команд.
Спасибо.