Android Question MsgBox2Async correct use

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Hi to all
since the introduction of asyncronous msgboxes, i lost a good part of love for B4A. As a matter of fact, a trivial action like to wait for user interaction, normally managed in "Modal" style (Windows Modal, I mean) became a nightmare, expecially in previous code written with "obsolete" MsgBoxes. My understanding is that, in practice, I must make Apps more or less without relying on the fact that the App waits for user answers. This adds real difficulties to my common Apps. Therefore I decided to try to understand better my faults on this subject, submitting to this community my problem. In the attached code, I have a List, that needs to be changed on User's choice. This code doesn't work, because the ModifyList returns immediately. Maybe the solution is to let the ModifyList sub to wait too.. but it is not so clear to me what to do.
Thanks in advance

B4X:
Private Sub Button1_Click
    Dim i As Int
 
   List1.Initialize
    
    For i=0 To 10
        List1.Add(i+1)
    Next
    
    Log("Before")
    For i=0 To 10
        Log(List1.Get(i))
    Next
    
    ModifyList(List1)
    
    Log("After")
    For i=0 To 10
        Log(List1.Get(i))
    Next
    
End Sub

private Sub ModifyList(L As List)
    Wait for (Confirm("Modify List?")) Complete (Res As Int)
    If Res=DialogResponse.POSITIVE Then
        Dim i As Int
        For i=0 To 10
            L.Set(i,10-i)
        Next
    End If
End Sub

private Sub Confirm(Msg As String) As ResumableSub
    Dim Res As Int
    Msgbox2Async(Msg, "Attention", "Yes", "", "No",Null, False)
    Wait For Msgbox_Result (Res As Int)
    Return Res
End Sub
 

Attachments

  • TestAsyncMsgbox.zip
    10.1 KB · Views: 35

LucaMs

Expert
Licensed User
Longtime User
You should no longer use any of the modal dialogs. They can cause your app to crash under some circumstances.
I do not agree. The user will reply to the msg within a few seconds and this will not compromise anything.
The O.S. might kill the process, but certainly not after a few seconds!
 
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Since your ModifyList Sub contains a "Wait For" statement, it is a resumable too, so you may need to call it too using a "Wait For"!
Yes, I suspected it too, and tried with no success, but, after this discussion, I think that I will retry... Maybe a second time I will get something.. Thanks you
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
I do not agree.
You may not agree but it is a fact. The OS will not kill the app as the modal mechanism keeps the app alive. However the modal mechanism can crash your app under certain circumstances - mainly to do with other messages posted to the app's message loop by the OS over which you have no control. In a production app you should never use modal dialogs.
 
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Hi. Thanks. LucaMs stimulated me to retry and I did. Apparently it works as I want. Thanks to all.
B4X:
Private Sub Button1_Click
    'xui.MsgboxAsync("Hello world!", "B4X")
    Dim i As Int

    List1.Initialize
    
    For i=0 To 10
        List1.Add(i+1)
    Next
    
    Log("Before")
    For i=0 To 10
        Log(List1.Get(i))
    Next
    
    wait for (ModifyList(List1)) complete (r As Int)
    
    If r=DialogResponse.POSITIVE Then
    
        Log("After")
        For i=0 To 10
            Log(List1.Get(i))
        Next
    End If
End Sub

private Sub ModifyList (L As List) As ResumableSub

    Wait for (Confirm("Modify List?")) Complete (Res As Int)

    If Res=DialogResponse.POSITIVE Then
        Dim i As Int
        For i=0 To 10
            List1.Set(i,"aa")
        Next
    End If
    Return Res
End Sub
 
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Anyway I think that this is only apparently resolving the problem... I mean: if other code out of "if r=DialogResponde.POSITIVE .. End If" exists, it will be executed anyway.. So, probably it is better to change totally the way of programming.. if possible..
 
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
No, sorry for previous message. It seems really to work, I attach the project showing that other code waits too.. If I see well..
 

Attachments

  • TestAsyncMsgbox.zip
    10.2 KB · Views: 34
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
The subtle mistake was to think that the Confirm sub called by the ModifyList was enough. This is wrong, evidently. We must pass the result to all the calling sub stack. It leaves me perplexed, but you can verify my code ... Thanks again to all.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
No, sorry for previous message. It seems really to work, I attach the project showing that other code waits too.. If I see well..
It seems ok, to me.

Just:
B4X:
    wait for (ModifyList(List1)) complete (r As Int)
   
    If r=DialogResponse.POSITIVE Then
        Log("After")
        For i=0 To 10
            Log(List1.Get(i))
        Next
    Else
        Log("The user has canceled the action")
    End If
(so you can check better.)


B4X:
private Sub ModifyList (L As List) As ResumableSub

    Wait for (Confirm("Modify List?")) Complete (Res As Int)

    If Res=DialogResponse.POSITIVE Then
        Dim i As Int
        For i=0 To 10
            L.Set(i,"aa") ' <--- L
        Next
    End If
    Return Res
End Sub


and remember that a resumable function can return any type of value, so even a boolean, string, OBJECT, ...
 
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Ok LucaMs. Forget about the "User canceled etc.".. My problem was to stop execution. It seems that stops, until the user answers.. then I will go on with other code. The example was very simple to focus the problem. I already thought to use the "Wait For" for the ModifyList sub, but it seemed too strange. At this point we have 3 "wait for" ... Anyway, it works.. The code is there.. if nobody says anything against it, I will go on in this way..
 
Upvote 0

Spavlyuk

Active Member
Licensed User
You don't have to use Wait For inside your confirm Sub.
B4X:
private Sub ModifyList (L As List) As ResumableSub
    Confirm("Modify List?")
    Wait For Msgbox_Result (Res As Int)

    If Res=DialogResponse.POSITIVE Then
        Dim i As Int
        For i=0 To 10
            L.Set(i,"aa")
        Next
    End If
    Return Res
End Sub

private Sub Confirm(Msg As String)
    Msgbox2Async(Msg, "Attention", "Yes", "", "No",Null, False)
End Sub

You can further reduce complexity by calling Confirm from Button1_Click.
B4X:
Private Sub Button1_Click
    'xui.MsgboxAsync("Hello world!", "B4X")
    Dim i As Int

    List1.Initialize
    
    For i=0 To 10
        List1.Add(i+1)
    Next
    
    Log("Before")
    For i=0 To 10
        Log(List1.Get(i))
    Next
    
    Confirm("Modify List?")
    Wait For Msgbox_Result (r As Int)
    
    If r=DialogResponse.POSITIVE Then
        ModifyList(List1)
        Log("After")
        For i=0 To 10
            Log(List1.Get(i))
        Next
    End If
    
    Log("at the end ...")
End Sub

private Sub ModifyList (L As List)
    For i=0 To 10
        L.Set(i,"aa")
    Next
End Sub

private Sub Confirm(Msg As String)
    Msgbox2Async(Msg, "Attention", "Yes", "", "No",Null, False)
End Sub
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
For cross platform, you can use xui.Msgbox2Async()

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    List1.Initialize
    Log("Before")
    For i = 0 To 10
        List1.Add(i + 1)
    Next
    Log(List1)
End Sub

Private Sub Button1_Click
    Dim sf As Object = xui.Msgbox2Async("Modify List?", "Attention", "Yes", "", "No", Null)
    Wait For (sf) Msgbox_Result (Result As Int)
    If Result = xui.DialogResponse_Positive Then
        Log("After")
        ModifyList
    End If
    Log(List1)
    Log("At the end ...")
End Sub

Private Sub ModifyList
    For i = 0 To 10
        List1.Set(i, "aa")
    Next
End Sub
 

Attachments

  • MsgBoxAsync.zip
    13.9 KB · Views: 30
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Aeric, it is clear that your code has no problems, but you modified the original structure of the example and my question was not that, mainly because it is not a real code flow, but an abstraction of a more complex situation. Thanks a lot anyway.
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
I had some older apps with this problem. Multiple calling subs leading to a Modal MsgBox.

The "Simple" solution was to use a "Wait For" in each of the calling subs all the way up the tree. In some cases, where a branch did not always NEED the Wait I duplicated the sub. Same sub, one resumable, one not. Ugly but got the job done and ultimately that is what it is all about.
 
Upvote 0

Sagenut

Well-Known Member
Licensed User
Longtime User
Wait For and Resumable Subs are two extremely powerful functions that solves many many cases.
They just need to be fully understood.
Often the problem is that we miss that the code flow will go back to some point where it can continue.
 
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
I had some older apps with this problem. Multiple calling subs leading to a Modal MsgBox.

The "Simple" solution was to use a "Wait For" in each of the calling subs all the way up the tree. In some cases, where a branch did not always NEED the Wait I duplicated the sub. Same sub, one resumable, one not. Ugly but got the job done and ultimately that is what it is all about.
Hi. Thanks for your comment. To be sincere, i did something similar to your suggestion, in the past. Not being distributable Apps, things went on, more or less. Only, this time, i wanted to submit the problem to the community, because, not being an Android/B4A guru, I had some doubts to be on the correct way. After this post I am more comfortable and the problem is resolved, or better, I have a better understanding of the situation. Thanks again.
 
Upvote 0

GiovanniPolese

Well-Known Member
Licensed User
Longtime User
Wait For and Resumable Subs are two extremely powerful functions that solves many many cases.
They just need to be fully understood.
Often the problem is that we miss that the code flow will go back to some point where it can continue.
Hi. I don't discuss the importance of the resumable subs etc (for anybody else than me). Only, as a seasoned Windows programmer, and not loving particularly Android, I had this difficulty. Nevertheless, forgive me: all this noise for deprecating MsgBoxes, which are substantially Modal DIalogs (and also Modal way is basically deprecate in B4A, and Android, as I learned now)? What sounded strange to me was the fact that the lack of Modal stuff was passed as "normal". In my Apps, 99% of dialogs and message boxes are Modal. Probably I didn't understand well the sitation. If I knew since the beginning that I must work always asyncronously, I could have done many things differently. I have many Apps with serial or internet communication which work asyncronously, with no problem. It was clear since the beginning and I did. Finding myself to manage the MsgBox deprecation was annoying, to be sincere. Ok. This is my problem, anyway. Luckily one of the best things of B4A is .. its community.. Thanks to all.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Hi. I don't discuss the importance of the resumable subs etc (for anybody else than me). Only, as a seasoned Windows programmer, and not loving particularly Android, I had this difficulty. Nevertheless, forgive me: all this noise for deprecating MsgBoxes, which are substantially Modal DIalogs (and also Modal way is basically deprecate in B4A, and Android, as I learned now)? What sounded strange to me was the fact that the lack of Modal stuff was passed as "normal". In my Apps, 99% of dialogs and message boxes are Modal. Probably I didn't understand well the sitation. If I knew since the beginning that I must work always asyncronously, I could have done many things differently. I have many Apps with serial or internet communication which work asyncronously, with no problem. It was clear since the beginning and I did. Finding myself to manage the MsgBox deprecation was annoying, to be sincere. Ok. This is my problem, anyway. Luckily one of the best things of B4A is .. its community.. Thanks to all.
I'll make everyone nervous (@Mahares and @Erel in primis šŸ˜ ) but I still think that modal MsgBox is not a "danger" for the "survival" of the app.

However, it can be avoided, if desired (but continue to use it if you want))
 
Upvote 0
Top