我在LWUIT中编写了一个针对J2ME手机(Sprint DuraXT)的应用程序。该应用程序适用于皮卡车和送货车司机。它接收来自后端调度系统的调度,该调度系统描述拾取并传递驱动程序必须进行的调度。作为驱动程序,执行拾取和交付,驱动程序输入发送回调度系统的状态信息。
现在,在处理提货或交货期间,可能会向驱动程序显示错误对话框(错误的字段输入),是/否确认对话框(确认某些操作)和信息对话框(指示驱动程序应该知道的某些状态)的)。
此外,还有一个后台线程正在侦听来自后端服务器的调度。在当前实现中,此后台线程还可以创建是/否确认对话框和信息对话框。这些对话框更像是一个警报,因为它们有相关的声音,但它们只是对话框。
只要这两个对话框没有“同时”发生,每个东西都按预期工作。您可以关闭对话框,应用程序按预期进行。
但是,当您在屏幕上并且已经显示一个对话框并且后台线程中出现了第二个对话框时,您有时会显示错误的屏幕并且它被“冻结”。例如。软键无效。
我的假设是线程之间存在争用对话框的竞争条件。它是这样的。 EDT被阻止,显示作为表单逻辑的一部分出现的对话框。后台线程也被阻止,显示一个对话框。现在,当EDT上显示的对话框被解除时,表单将被恢复,但EDT可能会关闭并显示另一个表单(通过show())。当后台线程显示的对话框被解除时,有时会恢复最初显示对话框时显示的表单。现在,显示屏显示的格式与EDT可能显示的格式不同。
很明显,这个问题是由后台线程活动产生的对话引起的。所以基本的问题是:“如何处理后台线程产生的对话框?”我有一些想法,但没有一个产生特别干净的实现。我希望有人不得不处理同样的问题并提出建议。
我尝试过同步对话框构造和显示,这样一次只能显示一个对话框。这肯定会改善UI,但不能完全解决问题。比赛在第一个对话框被解除时开始。以下是其他一些想法,
有什么想法吗?
答案 0 :(得分:1)
经过一些实验,我确实找到了解决方案。因为对话是涉及是/否对话和数据库查询的更加复杂的操作的一部分,我发现我必须将整个操作包装在实现Runnable接口的类中。然后我通过Display.getInstance()。callSeriallyAndWait(runnable)运行动作。
所以其他人可能会从这个讨论中受益,这里是其中一个类的示例,其中的操作嵌入在run方法中。
private class CancelOrder implements Runnable {private KWMap order; public CancelOrder(KWMap order) { this.order = order; } public void run() { String orderNum = getString(order, OrderTable.ORDER_NUM); if (legStatusTable.isOrderStarted(orderNum) && !orderTable.isOrderComplete(order)) { String msg = "You received a cancellation message for Order " + orderNum + " which has been started but is not finished." + "\nDo you want to keep it?"; if (app.yesNoDialog(msg, "Yes", "no")) { sendCancelResponse(order, "Yes", ""); } else { deleteOrder(orderNum); sendCancelResponse(order, "No", ""); } } else { // order has neither been started nor completed. deleteOrder(orderNum); sendCancelResponse(order, "Yes", ""); app.alertDialog("Dispatcher cancelled Order " + orderNum); } } }
这里的关键是该操作包含逻辑,具体取决于用户如何响应是/否对话框以及底层数据库和消息传递子系统上的操作。除了Dialogs之外,此操作中没有任何内容阻止EDT超过几百毫秒,因此应用程序运行非常顺利。应用程序可以同时处理堆叠在彼此之上的dislogs,这是让这些操作在后台(非EDT)线程上运行的简单apporach的问题。