Android Question Translating an old app to B4XPages: Code Flow in B4XPage_Created and B4XPage_Appear

GuyBooth

Active Member
Licensed User
Longtime User
I am trying to confirm how the code flow works between these two events ...
I have a significant amount of code in my MainPage B4XPage_Created sub, including creating (but not showing) 4 additional pages which themselves have a fair amount of code in their creation events.
From what I can see, the MainPage B4XPage_Appear code starts running before the B4XPage_Created code has completed. Other pages don't have this problem because I control each of them with B4XPages.ShowPage()

Am I correct in my analysis?
If so, How do I make sure that code in the MainPage B4XPage_Created is completed before the code in B4XPage_Appear?
 

GuyBooth

Active Member
Licensed User
Longtime User
I have one line that calls a Wait For Splash Screen complete.
I don't see any Sleeps or Wait Fors in the Creation code - there are some in the Appear code which I would expect to have the make the code flow better rather than worse.
I have changed the code to separate the "Create" from the Show
The code in B4XMainPage was :
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Wait For (ShowSplashScreen) Complete (Unused As Boolean)
    Root.LoadLayout("tmm_main_std")
    ... more code

  TMM_Preferences.Initialize
  ' The code was:
  B4XPages.AddPageAndCreate("B4XPTMM_PreferencesID", TMM_Preferences)
  ' And is now
  B4XPages.AddPage("B4XPTMM_PreferencesID", TMM_Preferences)
  ... some other code
End Sub

Private Sub B4XPage_Appear
    rp.CheckAndRequest(rp.PERMISSION_READ_PHONE_STATE)
    ' Activity_PermissionResult is called by the CheckAndRequest call
    Wait For B4XPage_PermissionResult (Permission As String, PResult As Boolean)
    If Not(PResult) Then
        Permissions_Denied
        Return
    End If
    .. more rp's ..
    Run_Main_Setup
End Sub

Sub Run_Main_Setup
  .. some code
  B4XPages.ShowPage("B4XPTMM_PreferencesID")
End sub

I'm making an assumption here that after "B4XPages.AddPage("B4XPTMM_PreferencesID", TMM_Preferences)" runs, the line " B4XPages.ShowPage("B4XPTMM_PreferencesID")" creates AND shows the page. This isn't clear to me in the documentation ...
 
Last edited:
Upvote 0

GuyBooth

Active Member
Licensed User
Longtime User
I have one line that calls a Wait For Splash Screen complete.
I don't see any Sleeps or Wait Fors in the Creation code - there are some in the Appear code which I would expect to have the make the code flow better rather than worse.
I have changed the code to separate the "Create" from the Show
The code in B4XMainPage was :
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
  TMM_Preferences.Initialize
  ' The code was:
  B4XPages.AddPageAndCreate("B4XPTMM_PreferencesID", TMM_Preferences)
  ' And is now
  B4XPages.AddPage("B4XPTMM_PreferencesID", TMM_Preferences)
  ... some other code
End Sub

Private Sub B4XPage_Appear
    rp.CheckAndRequest(rp.PERMISSION_READ_PHONE_STATE)
    ' Activity_PermissionResult is called by the CheckAndRequest call
    Wait For B4XPage_PermissionResult (Permission As String, PResult As Boolean)
    If Not(PResult) Then
        Permissions_Denied
        Return
    End If
    .. more rp's ..
    Run_Main_Setup
End Sub

Sub Run_Main_Setup
  .. some code
  B4XPages.ShowPage("B4XPTMM_PreferencesID")
End sub

I'm making an assumption here that after "B4XPages.AddPage("B4XPTMM_PreferencesID", TMM_Preferences)" runs, the line " B4XPages.ShowPage("B4XPTMM_PreferencesID")" creates AND shows the page. This isn't clear to me in the documentation ...
If I remove the Wait For Splash Screen reference, the Code Flow problem goes away, but This problem persists.
If on the other hand I remove the Wait For Splash Screen reference and also revert to "B4XPages.AddPageAndCreate("B4XPTMM_PreferencesID", TMM_Preferences)" I think the code flow problem goes away and This Problem also seems to be resolved...
I have more work to do to confirm it, and I now have to find another way to show my the Splash screen.
 
Upvote 0

GuyBooth

Active Member
Licensed User
Longtime User
If on the other hand I remove the Wait For Splash Screen reference and also revert to "B4XPages.AddPageAndCreate("B4XPTMM_PreferencesID", TMM_Preferences)" I think the code flow problem goes away and This Problem also seems to be resolved...
I have more work to do to confirm it, and I now have to find another way to show my the Splash screen.

Unfortunately - the problem is still there.
 
Upvote 0

GuyBooth

Active Member
Licensed User
Longtime User
I would have put the permission request in B4XPage_Created and not in B4XPageAppear.
Every time you come back to B4XMainPage from another page, B4XPageAppear will be executed.
This puts many Wait For elements into the B4XPage_Created, which I think I was trying to eliminate, based on Erel's comment earlier in this thread.
Not saying it's wrong ... but I seem to be dealing with multiple problems at the moment and not finding their root cause.
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
I found a lot of wait fors had to be added when converting. I like to load as much as possible in the background but found it just got too complicated if there was any possiblity of a message box or error happening. Better to wait...
 
Upvote 0

GuyBooth

Active Member
Licensed User
Longtime User
I ended up with my "wait fors" with "Permissions Reqeusts" in the Page_Created sub, and then added some code to make sure the code in the Page_Appear sub didn't begin until everything was ready. At the end of the Page_Appear sub I called the .ShowPage to move on to the next page.
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    ....
    Private bPageCreated As Boolean
End Sub
'
Private Sub B4XPage_Created (Root1 As B4XView)
    'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
    Dim sCodeName As String = "B4XMainPage_Created"
    LogColor($"Sub: ${sCodeName}"$, ModColour)
    Root = Root1
    Root.LoadLayout("tmm_main_std")
    Try
        Dim cs As CSBuilder
        B4XPages.SetTitle(Me, cs.Initialize.Color(xui.Color_RGB(210,105,30)).Append("The Music Machine").PopAll)
        ' Initialize the TMM_Run activity class with TMM_RunPage
        TMM_Run.Initialize
        TMM_DBUpdates.Initialize
        ' Add the page before we call any wait for subs
        B4XPages.AddPage("B4XPTMM_RunID", TMM_Run)  
        .... etc
        For Each permission As String In Array(rp.PERMISSION_READ_PHONE_STATE,rp.PERMISSION_WRITE_EXTERNAL_STORAGE,rp.PERMISSION_RECORD_AUDIO)
            rp.CheckAndRequest(permission)
            Log("requesting: " & permission)
            Wait For B4XPage_PermissionResult (permission As String, Result As Boolean)
            If Not(Result) Then
                            Msgbox2Async ("You must restart The Music Machine and agree to all the permissions for The Music Machine to continue.", _
                    "The Music Machine", _
                    "", "OK", "",cmTMM.gbmpLogo36x36,False)
                Wait for MsgBox_Result
                cmTMM.gbAppClosing = True
                B4XPages.ClosePage(Me)
            End If
            .... etc
            bPageCreated = True
    Catch
        Dim sErrorMsg As String = "TBCI App Error: " & CRLF & LastException
        LogColor ($"${sCodeName}:${sErrorMsg}"$, Colors.Red)
        MsgboxAsync (sErrorMsg, sCodeName)
    End Try
End Sub
'           
Private Sub B4XPage_Appear
    Dim sCodeName As String = "B4XMainPage_Appear"
    LogColor($"Sub: ${sCodeName}"$, ModColour)
    LogColor($"Logs in Main are in this colour"$, ModColour)
    Start = DateTime.Now
    ' Not in the list? AddPermission(android.permission.WAKE_LOCK)
    ' Start the main setup routines
    Run_MainSetup1
    ' Ask if user wants to load updates
    Run_MainSetup2
    ' After PageCreated is complete, allow the flash screen to show for FLASHONSCREEN_MSECS then go to the Run page
    Do While Not(bPageCreated)
        Sleep(500)
    Loop
    LogColor($"B4XMainPage_PageCreated is finished: ${bPageCreated}"$, ModColour)
    B4XPages.ShowPage("B4XPTMM_RunID")
End Sub
So far this is working, but I haven't yet fully tested everything with a new intallation ...
 
Upvote 0

GuyBooth

Active Member
Licensed User
Longtime User
So far this is working, but I haven't yet fully tested everything with a new intallation ...
This code runs fine once the permissions are in place, but I have run into problems when it is run the first time when no permissions have yet been granted.
For reasons that I don't understand, the B4XPage_Appear code runs every time a permission is requested. From the logs below, it looks as though the Main Activity_Resume is run each time.
Is this something to do with the delegations?
B4X:
Logger connected to:  samsung SM-P610
--------- beginning of main
Copying updated assets files (29)
** Activity (main) Create (first time) **
Sub: TMM_Main A_C
*** mainpage: B4XPage_Created
Sub: B4XMainPage_Created
dscale is 1.6780444444444444
Device Manufacturer:  Model:
Activity Width: 1200 Height: 1832 pnlBase Width: 1200 Height: 1832
Sub cmTMM.Initialize
Logs in the TMM code module are in this colour
    Device Scale: 1.5
    Height: 1928
    Width: 1200
    Screen Size: 9.462264450458417
requesting: android.permission.READ_PHONE_STATE
*** mainpage: B4XPage_Appear
** Activity (main) Resume **
Sub: Main A_R
Sub: B4XMainPage_Appear
Logs in Main are in this colour
Sub: B4XMainPage_Run_MainSetup1
Sub cmTMM.LoadSettings
Settings loaded is true
Sub: B4XMainPage_Run_MainSetup2
DB Update File Name will be MusicBase_Update.db
** Activity (main) Pause event (activity is not paused). **
*** mainpage: B4XPage_Disappear [mainpage]
Sub: B4XMainPage_Disappear
*** mainpage: B4XPage_PermissionResult [mainpage]
** Activity (main) Resume **
Sub: Main A_R
*** mainpage: B4XPage_Appear [mainpage]
result: android.permission.READ_PHONE_STATE, true
requesting: android.permission.WRITE_EXTERNAL_STORAGE
Sub: B4XMainPage_Appear
Logs in Main are in this colour
Sub: B4XMainPage_Run_MainSetup1
Settings loaded is true
Sub: B4XMainPage_Run_MainSetup2
DB Update File Name will be MusicBase_Update.db
** Activity (main) Pause event (activity is not paused). **
*** mainpage: B4XPage_Disappear [mainpage]
Sub: B4XMainPage_Disappear
*** mainpage: B4XPage_PermissionResult [mainpage]
** Activity (main) Resume **
Sub: Main A_R
*** mainpage: B4XPage_Appear [mainpage]
result: android.permission.WRITE_EXTERNAL_STORAGE, true
requesting: android.permission.RECORD_AUDIO
Sub: B4XMainPage_Appear
Logs in Main are in this colour
Sub: B4XMainPage_Run_MainSetup1
Settings loaded is true
Sub: B4XMainPage_Run_MainSetup2
DB Update File Name will be MusicBase_Update.db
** Activity (main) Pause event (activity is not paused). **
*** mainpage: B4XPage_Disappear [mainpage]
Sub: B4XMainPage_Disappear
*** mainpage: B4XPage_PermissionResult [mainpage]
** Activity (main) Resume **
Sub: Main A_R
*** mainpage: B4XPage_Appear [mainpage]
result: android.permission.RECORD_AUDIO, true
Requesting MANAGE_EXTERNAL_STORAGE permission
Requesting permission
Sub: B4XMainPage_Appear
Logs in Main are in this colour
Sub: B4XMainPage_Run_MainSetup1
Settings loaded is true
Sub: B4XMainPage_Run_MainSetup2
DB Update File Name will be MusicBase_Update.db
...
Note that Sub: Main A_R is a log entry from Activity_Resume in Main.
I can probably program my way around this, but it is strange to me that I have to ...
 
Upvote 0

GuyBooth

Active Member
Licensed User
Longtime User
In fact it was more complicated, I had to add "interlocks" to force the code threads to only advance in the correct sequence.
 
Upvote 0
Top