2012-12-14 30 views
2

我已经编写了一个针对J2ME手机(Sprint DuraXT)的LWUIT应用程序。该应用程序适用于皮卡车和送货车司机。它接收来自后端调度系统的调度信息,描述拾音器并提供驱动程序必须提供的信息。作为驱动程序,执行拾取和交付,驱动程序输入发送回调度系统的状态信息。如何处理后台线程上显示的LWUIT对话框

现在,在拾取或交付处理过程中,可能会向驱动程序提供错误对话框(不正确的字段输入),是/否确认对话框(确认某个动作)和信息对话框(指示驾驶员应该意识到)。

此外,还有一个后台线程监听来自后端服务器的调度。在当前的实现中,这个后台线程还可以创建yes/no确认对话框和信息对话框。这些对话框更像是一个警报,因为它们有相关的声音,但它们只是对话框。

只要这两个对话不“同时”发生,每件事情都按预期工作。您可以关闭对话框,应用程序按预期进行。

然而,当你在屏幕上,并且有一个对话框已经显示并且后台线程中出现第二个对话框时,你有时会显示错误的屏幕并且它被“冻结”。例如。软键不起作用。

我的假设是在解除对话的线程之间存在争用条件。它是这样的。 EDT被阻止显示作为表单逻辑的一部分出现的对话框。后台线程也被阻止显示一个对话框。现在,当EDT上显示的对话框被解除时,表单将被恢复,但EDT可能会关闭并显示另一个表单(通过show())。当背景线程显示的对话框被取消时,对话框最初显示时显示的窗体有时会被恢复。现在,显示屏显示的形式与EDT可能显示的形式不同。

很明显,这个问题是由后台线程活动产生的对话引起的。所以基本的问题是:“如何处理后台线程产生的对话框?”我有一些想法,但没有一个产生一个特别干净的实现。我希望有人不得不面对同样的问题并提出建议。

我已经尝试同步对话框的构造和显示,以便一次只能显示一个对话框。这无疑改进了用户界面,但并未完全解决问题。当第一个对话被解散时,比赛就开始了。这里有一些其他的想法,

  1. 如果一个对话框由EDT以外的线程显示,当对话框关闭时,调用显示堆栈顶部窗体上的show。这有点破解,但可能是一种解决方法。
  2. 运行对话框以在EDT上由后台线程显示。有几种方法可以做到这一点,但问题是它会解决问题吗?将使用EventDispatcher帮助吗?我已经尝试过使用EventDispatcher来触发包含对话框的子类的ActionEvent作为源。该子类包含一个show()方法,该方法调用Dialog show方法的正确形式。持有EventDispatcher的类(全局应用程序)监听这些事件。当事件到达时,show方法被调用。对于信息对话,只要他们被解雇就可以继续执行,这应该起作用。对于是/否对话框,您可能需要创建类似于yes/no的回调来处理逻辑中的分叉。不明显的是,这是否会实际上序列化EDT线程上对话框的处理。这看起来很复杂。

任何想法?

回答

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); 
     } 
    } 
} 

这里的关键是,动作包含的逻辑取决于用户如何响应是/否对话框选择,且有基础数据库和信息子系统操作为好。除了对话框之外,此操作中没有任何内容会阻止EDT超过几百毫秒,因此应用程序运行非常顺畅。该应用程序可以协同处理dislog堆叠在彼此之上,这是让这些操作在后台(非EDT)线程上运行的简单应用的问题。

相关问题