Reputation: 99
I have written an application in LWUIT targeted for a J2ME phone (Sprint DuraXT). The application is for pickup and delivery van drivers. It receives dispatches from a back-end dispatching system that describe pickups and delivers the driver must make. As the drivers, execute the pickups and deliveries, the driver enters status information that is sent back to the dispatching system.
Now, during the processing of a pickup or delivery, the driver may be presented with error dialogs (incorrect field entry), yes/no confirmation dialogs (confirming some action) and information dialogs (indicating some status the driver should be aware of).
In addition, there is a background thread listening for dispatches coming from the back-end server. In the current implementation, this background thread can also create yes/no confirmation dialogs and information dialogs. These dialogs are more like an alert as they have an associated sound, but they are simply dialogs.
As long as these two dialogs do not occur “simultaneously” every thing works as expected. You can dismiss the dialogs and the app proceeds as expected.
However, when you are on a screen and there is a dialog already showing and a second one from the background thread occurs, you sometime wind up with the wrong screen showing and it is “frozen”. E.g. the soft keys have no effect.
My hypothesis is that there is a race condition between the threads that are dismissing the dialogs. It goes like this. The EDT is blocked showing the dialog that arises as part of the form’s logic. The background thread is also blocked showing a dialog. Now when the dialog showing on the EDT is dismissed, the form is restored, but the EDT may go off and display another form (via show()). When the dialog displayed by the background thread is dismissed, the form which was showing when the dialog was initially displayed is sometimes restored. Now, the display shows a different form than the one the EDT might have shown.
It is pretty clear that this problem is caused by the dialogs resulting from the activities of the background thread. So the basic question is: “How to handle the dialogs arising from the background thread?” I have some thoughts but none yield a particularly clean implementation. I am hoping somebody has had to deal with this same problem and has a suggestion.
I have tried synchronizing the dialog construction and display so that only one dialog can get displayed at a time. This certainly improves the UI, but does not fully resolve the problem. The race begins when the first dialog is dismissed. Here are some other ideas,
Any ideas?
Upvotes: 2
Views: 419
Reputation: 99
I actually hit upon the solution after a bit of experimentation. Because the Dialogs are part of a more compilcated action involving yes/no Dialogs and database queries, I found I had to wrap the whole action in a class which implements the Runnable interface. Then I run the action via Display.getInstance().callSeriallyAndWait(runnable).
So others may benefit from this discussion, here is a example of one of these classes with the action embedded in the run method.
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); } } }
The key thing here is that the action contains logic depending on how a user responds to a yes/no Dialog and there are operations on an underlying database and messaging subsystem as well. Except for the Dialogs, nothing in this action blocks the EDT for more than a few 100s of milliseconds, so the application runs very smoothly. The app coorectly handles dislogs stacking on top of each other which was a problem with the simple apporach of letting these actions run on the background (non EDT) thread.
Upvotes: 1