Starting from B4A v7.0 the following warning will appear for DoEvents calls:
DoEvents is deprecated. It can lead to stability issues. Use Sleep(0) instead (if really needed).
The purpose of DoEvents was to allow the UI to be updated while the main thread is busy. DoEvents which shares the same implementation as the modal dialogs implementation, is a low level implementation. It accesses the process message queue and runs some of the waiting messages.
As Android evolved, the handling of the message queue became more sophisticated and fragile.
The reasons for deprecating DoEvents are:
1. It is a major source for instability issues. It can lead to hard to debug crashes or ANR (application not responding) dialogs. Note that this is also true for the modal dialogs (such as Msgbox and InputList).
2. There are better ways to keep the main thread free. For example use the asynchronous SQL methods instead of the synchronous methods.
3. It doesn't do what many developers expect it to do. As it only handles UI related messages, most events could not be raised from a DoEvents call.
4. It is now possible to call Sleep to pause the current sub and resume it after the waiting messages are processed. Sleep implementation is completely different than DoEvents. It doesn't hold the thread. It instead releases it while preserving the sub state.
Unlike DoEvents which only processed UI related messages, with Sleep all messages will be processed and other events will be raised.
(Note that using Wait For to wait for an event is better than calling Sleep in a loop.)
With that said, DoEvents is still there and existing applications will work exactly as before.
Dialogs
Modal dialogs = dialogs that hold the main thread until the dialog is dismissed.
As written above, modal dialogs share the same implementation as DoEvents. It is therefore recommended to switch to the new async dialogs instead. Using Wait For it is really a simple change:
Instead of:
You should use:
Wait For doesn't hold the main thread. It instead saves the current sub state and releases it. The code will resume when the user clicks on one of the dialog buttons.
The other similar new methods are: MsgboxAsync, InputListAsync and InputMapAsync.
With the exception of MsgboxAsync, the new methods also add a new cancelable parameter. If it is true then the dialog can be dismissed by clicking on the back key or outside the dialog. This is the default behavior of the older methods.
As other code can run while the async dialog is visible, it is possible that multiple dialogs will appear at the same time.
If this case is relevant for your app then you should set the sender filter parameter in the Wait For call:
This allows multiple messages to be displayed and the result events will be handled correctly.
Bug in B4A v7.00 / 7.01 - Async dialogs should not be used in classes as the Result event will be raised in the Activity instead of the class module. This is fixed for the next update.
DoEvents is deprecated. It can lead to stability issues. Use Sleep(0) instead (if really needed).
The purpose of DoEvents was to allow the UI to be updated while the main thread is busy. DoEvents which shares the same implementation as the modal dialogs implementation, is a low level implementation. It accesses the process message queue and runs some of the waiting messages.
As Android evolved, the handling of the message queue became more sophisticated and fragile.
The reasons for deprecating DoEvents are:
1. It is a major source for instability issues. It can lead to hard to debug crashes or ANR (application not responding) dialogs. Note that this is also true for the modal dialogs (such as Msgbox and InputList).
2. There are better ways to keep the main thread free. For example use the asynchronous SQL methods instead of the synchronous methods.
3. It doesn't do what many developers expect it to do. As it only handles UI related messages, most events could not be raised from a DoEvents call.
4. It is now possible to call Sleep to pause the current sub and resume it after the waiting messages are processed. Sleep implementation is completely different than DoEvents. It doesn't hold the thread. It instead releases it while preserving the sub state.
Unlike DoEvents which only processed UI related messages, with Sleep all messages will be processed and other events will be raised.
(Note that using Wait For to wait for an event is better than calling Sleep in a loop.)
With that said, DoEvents is still there and existing applications will work exactly as before.
Dialogs
Modal dialogs = dialogs that hold the main thread until the dialog is dismissed.
As written above, modal dialogs share the same implementation as DoEvents. It is therefore recommended to switch to the new async dialogs instead. Using Wait For it is really a simple change:
Instead of:
B4X:
Dim res As Int = Msgbox2("Delete?", "Title", "Yes", "Cancel", "No", Null)
If res = DialogResponse.POSITIVE Then
End If
B4X:
Msgbox2Async("Delete?", "Title", "Yes", "Cancel", "No", Null, False)
Wait For Msgbox_Result (Result As Int)
If Result = DialogResponse.POSITIVE Then
'...
End If
Wait For doesn't hold the main thread. It instead saves the current sub state and releases it. The code will resume when the user clicks on one of the dialog buttons.
The other similar new methods are: MsgboxAsync, InputListAsync and InputMapAsync.
With the exception of MsgboxAsync, the new methods also add a new cancelable parameter. If it is true then the dialog can be dismissed by clicking on the back key or outside the dialog. This is the default behavior of the older methods.
As other code can run while the async dialog is visible, it is possible that multiple dialogs will appear at the same time.
If this case is relevant for your app then you should set the sender filter parameter in the Wait For call:
B4X:
Dim sf As Object = Msgbox2Async("Delete?", "Title", "Yes", "Cancel", "No", Null, False)
Wait For (sf) Msgbox_Result (Result As Int)
If Result = DialogResponse.POSITIVE Then
'...
End If
Bug in B4A v7.00 / 7.01 - Async dialogs should not be used in classes as the Result event will be raised in the Activity instead of the class module. This is fixed for the next update.
Last edited: