Android Question App hangs when Phone is idle for sometime and when the running logic of the control is 'inside a Do-While Loop' - reg.

beelze69

Active Member
Licensed User
Longtime User
Hi,

I have an issue with a B4A Pages app.

I have a Main Menu Page called 'MainMenu'.

The app has different pages viz. 'Pg1' , 'Pg2' etc.

Now suppose I am in page 'Pg1' and if I leave the b4A App 'idle' for sometime, I want the control to go directly to the Main Menu.

for this I have written the following code:

B4X:
Sub Activity_Pause (UserClosed As Boolean)
    Log("B4X Activity Pause event triggered")
    B4XPages.Delegate.Activity_Pause
    B4XPages.ShowPageAndRemovePreviousPages( "MainPage")
End Sub

However, my App hangs when I again go the 'Pg1'.

What am I doing wrong ?

Requesting for guidance on the same.

Thanks
 

beelze69

Active Member
Licensed User
Longtime User
You shouldn't modify the template code. Your code cannot work.

You should instead handle the B4XPage_Background event.
Hi Erel,

That means if I have say 5 Pages, then I have to write the code in the B4XPage_Background event of all the 5 pages to take control to the MainMenu

Kindly correct me if I am wrong.

The actual issue is the following:

In one b4X Page of my app, I am invoking a DateTemplate control

with

B4X:
Private Sub btnSelectDate_Click
    Wait For (GetDateTodayOnWards) Complete ( Ticks As Long)

 
    Log(Ticks)

 
 
End Sub


B4X:
Private Sub GetDateTodayOnWards As ResumableSub
Dim cs as CSBuilder
    Do While True
Wait For (Dialog.ShowTemplate( DateTemplate,   "",  "", "")) Complete (Result As Int)
        Dim days As Int = DateUtils.PeriodBetweenInDays( DateTime.Now, DateTemplate.Date).Days
        If days < 0 Then
            DateTemplate.Date = DateTime.Now
            Dialog.BodyTextColor=xui.Color_White
            Dialog.Title = cs.Initialize.Size(20).Append("Message").PopAll
            Wait For (Dialog.Show( "Select current or future date",  "Ok",  "", "")) Complete (Result As Int)
        Else
            Return DateTemplate.Date
        End If
    Loop
    Return 0
End Sub


Now the above logic works fine. However, when I leave the 'phone idle for sometime' when the GUI is showing this particular b4x Page and when I am inside this loop without selecting any date value , it gets 'hung'.[As per the logic, either I have to select a current or futuristic date from the DateTemplate, otherwise it will not exit the loop]...

So in order to come out of this 'hung situation' , I was thinking of taking the control to the 'MainMenu'..

Note: In my testing so far, I have noted that the app 'recovers from idle mode' properly without hanging in all other gui interfaces(read b4x Pages) except when I am in this particular page and inside this 'particular Do-While loop'..

Requesting for guidance on how to resolve this..
 
Last edited:
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Add some logs and find out why it doesn't exit the loop.
Hi Erel,

What I mean is that there is no problem with the logic/looping.. And it is perfectly normal for an end-user to keep inputting a past date and thus remain inside the loop or simply do nothing(go out for a cup of tea and not come back for an hour or two) without inputting anything on the datetemplate .

The issue is that when the app comes back to the foreground, it is unable to remember that it was inside this loop before it moved to the background. So either the App has to be made aware that it was inside such loops when it comes 'alive' from the background or the programmer has to write code to come out of such loops (wherever they are lying in the code) when the App moves to the background

So my request is - is there a way to add another condition to the loop that would set some flag that the android app has moved to the background so that such loops are exited.....with a 'standard logic for such ways of loop exits to take the control to the main menu' ... Then maybe that would solve the problem.

Secondly, I feel that the android OS should be able to handle such conditions on its own and not leave it to the programmer to handle - I mean when the process comes alive again then it has to understand that it was last inside this loop and continue to accept the end-user response which it was programmed to do before it got pushed in the background... but here the android OS is unable to remember that..... It simply hangs...

Requesting for further guidance,

Thanks...
 
Last edited:
Upvote 0

agraham

Expert
Licensed User
Longtime User
And it is perfectly normal for an end-user to simply wait there without inputting anything on the datetemplate or keep inputting a past date and thus remain inside the loop.
Sorry but no. Android, like most modern OS with a GUI is event driven. You should structure your program to not rely on looping. In the old days this was one of our biggest hurdles to overcome when retraining realtime software engineers to work on desktop systems with GUIs. They wanted to put everything in loops whereas GUI apps already have a loop running - the message loop, and all the events are called from this loop which is managed by the OS.

Secondly, I feel that the android OS should be able to handle such conditions on its own - I mean when the process comes alive again then it has to understand that it was last inside this loop and continue to accept the end-user response which it was all the time doing before it got pushed in the background... but here the android OS is unable to remember that..... It simply hangs...

Your supposition that it is running inside the loop is incorrect. I'm afraid that your mental model of what is happening is wrong. Invoking Wait For actually returns from your GetDateTodayOnWards Sub to the app message loop and normal Androidy things, including events, happen until the user dismisses the Dialog. This is nothing to do with Android, Resumable Subs are a B4X concept.

I have never seen a problem with putting an app in the background with a pending Wait For. Android dismissses the Dialog and the Sub is never re-entered to complete Wait For. (@Erel - a thought. Does this leave an orphaned ResumableSub instance or does it get cleaned up?) I don't see how the app can actually 'hang'. What is the manifestation of this presumed hang?
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
The issue is that when the app comes back to the foreground, it is unable to remember that it was inside this loop before it moved to the background.
Ah! I've just realised the significance of this. This is what Android does. All Dialogs are non-modal in Android and are dismissed when the app goes to the background. You would have to program this yourself. Possibly use a flag in Globals to say when you are in the Sub and invoke the Sub again when the page becomes visible again. Or better still restructure your app to avoid the need to restart it at all.
 
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Sorry but no. Android, like most modern OS with a GUI is event driven. You should structure your program to not rely on looping. In the old days this was one of our biggest hurdles to overcome when retraining realtime software engineers to work on desktop systems with GUIs. They wanted to put everything in loops whereas GUI apps already have a loop running - the message loop, and all the events are called from this loop which is managed by the OS.



Your supposition that it is running inside the loop is incorrect. I'm afraid that your mental model of what is happening is wrong. Invoking Wait For actually returns from your GetDateTodayOnWards Sub to the app message loop and normal Androidy things, including events, happen until the user dismisses the Dialog. This is nothing to do with Android, Resumable Subs are a B4X concept.

I have never seen a problem with putting an app in the background with a pending Wait For. Android dismissses the Dialog and the Sub is never re-entered to complete Wait For. (@Erel - a thought. Does this leave an orphaned ResumableSub instance or does it get cleaned up?) I don't see how the app can actually 'hang'. What is the manifestation of this presumed hang?
Hi Agraham,

Thanks for your insightful reply.

My request to you .. can you show me with an example as to how you will ensure a clean transfer of control to main menu from such loops when android pushes the app to the background....


What is happening is that 'if I write a code in the B4XPage_Background event (as suggested by Erel in his first reply) to take the control to the main menu.. it works fine and the control moves to the Main Menu ... now from there I am able to operate all the above pages ... But when I come again to this particular 'Date Template ' (i.e. in logic I have entered the Do while loop again).. I am unable to exit this Date Template... The app hangs ... This means this loop has not been properly exited by Android when the 'app was pushed to the background' and it 'remembers something about it'... You have mentioned that all Dialogs are non-modal and are dismissed when the app goes to the background... So if that is the case, why does android remember that 'it was inside this loop' before it was pushed to the background (because I don't see any reason for android to behave in a funny way only when it comes back again into this loop .. this means it remembers something about it) ?

Requesting for guidance on the same.

Thanks..
 
Last edited:
Upvote 0

agraham

Expert
Licensed User
Longtime User
This means this loop has not been properly exited by Android when the 'app was pushed to the background'...
Wrong sorry. Read how Resumable Subs actually work. Android has nothing to do with properly exiting the loop because it's not a real loop if it contains a Wait For. The loop is actually unwound by the Wait For and returns to the message loop to let everything carry on as usual.

 
Upvote 0

agraham

Expert
Licensed User
Longtime User
So if that is the case, why does android remember that 'it is inside this loop' ?
It doesn't because Wait For is managed by B4A, not Android. Where is Android 'remembering' anything? As I said above I think that your mental model of what is happening is wrong because you haven't got the correct model of what Resumable Subs are.
 
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
It doesn't because Wait For is managed by B4A, not Android. Where is Android 'remembering' anything? As I said above I think that your mental model of what is happening is wrong because you haven't got the correct model of what Resumable Subs are.

Agraham,

A request... can you guide me with an example on how to solve such problem..(my Wait for loop is already in the code I have posted above) ..... To tell you honestly I am unable to figure out how to solve this issue... I find it pretty fishy that my app should be able to work fine in all other modules except when it 'again enters the datetemplate gui' (which was where I left it before it got pushed to the background)....

Requesting for guiding me out of this issue.

Thanks..
 
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Sorry, but I don't understand what your problem actually is. You say it 'hangs' but don't qualify what you mean by hang. My suspicion is that the app is behaving as it is coded and you are expecting something different.
The app works fine when it comes back to the foreground in all other modules but when the end-user invokes the datetemplate gui again.. it does not take any click... When I press a day value in the datetemplate, the app does not respond at all.. none of the keys work... That is why I keep saying that 'it remembers something about its last presence there' (before it was pushed to the background) ...

However, when I explicitly 'kill the app from the cache' and then again invoke the app again, everything works fine as usual !! ... including the datetemplate gui...

So..the issue is there only if I am in the datetemplate gui BEFORE the 'app went to the idle state'... That's why I keep saying that it remembers something...
 
Last edited:
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
I tried to replace it with a local Dialog declared as dim inside the subroutine GetDateTodayOnWards .. but still the app hangs when it is goes again into that datetemplate gui after coming 'to the foreground'...

I will post sample code in an hour or two...
 
Last edited:
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Hi Agraham,

I have posted the sample code...

It is a simple datetemplate taken from the b4xLib..

I have just modified it to identify a 'LONG CLICK'..

How to simulate the 'Hung situation'..

Keep the Datetemplate GUI visible (all dates are shown) and leave the phone idle for sometime..
(Do not select any day of the dates from the calender immediately when the screen goes off in the idle mode - it works fine that time !)..

In my phone after the screen goes off..I wait for another 2-3 minutes..

Then I press the right button to 'make the screen on'.

I have a XIAOMI Note 7(by the way)..

Now at this stage, if I attempt to select any day from the datetemplate it will not work...

Now if you 'kill the app from the cache' and start again.. everything will work normal..
i.e. it will work normal till you again make the phone idle with the datetemplate displayed on the screen in the manner mentioned above...Then it will again hang...

Requesting you to solve this problem..

Thanks..
 

Attachments

  • testCode.zip
    12.7 KB · Views: 75
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Move your Dialog Initialization from B4xPage_Appear() to B4XPage_Created(). You are re-initializing Dialog when it comes back from the background while it is still displayed..
Thank you Agraham !

It worked !!.. So that was where the problem was .. And I was all the time thinking that I have done everything right...

Thank you very much for guiding me to resolve this issue.
 
Upvote 0
Top