All is well in the splash screen business!
My goal, right from the beginning, was to create a splash screen (welcome msg, logo, etc....) that I could "attach" to any application, hence my quest for as much "isolation" as possible between the 'real app' and the 'splash'. So Klaus, I took your idea of a 'main panel' to control visibility (from this thread) but i really didn't like having to deal with the main panel,layout or whatever in the tmr_tick event.
So i tried working with 2 activities, main & splash. That opened a can of worms as referred to by Jim Brown in this thread
I don't want to switch back and forth between 2 apps, just to show one app (splash) and 'forget' about it once it is finished and the main app is shown. Starting splash on firsttime else showing main panel is achieved by:
but that will cause the pnlMain to be INVISIBLE after the splash.
So how to show it on the 1st time? (remember that i do NOT want to deal with pnlMain in the tmr_tick event of the splash!)
One solution is to make pnlMain visible even on FirstTime, like this:
but this will briefly show the main panel BEFORE the splash screen - not what i want
Another solution is to show it on resume:
No good! Must read Erel's Activities Life Cycle again! Resume is called right after Create so this solution is basically just like the first one.
The real solution is to show pnlMain in Resume BUT CONDITIONALLY! Only after the splash has finished!
This is achieved with a semaphore that signals when the splash has finished.
The semaphore is declared in the splash activity (as much isolation!) process globals and is initialized and accessed in the main, so assuming the splash activity is called SplashMod, the resume code will have to be:
One more thing is left to deal with. When the user quits the main app with the back key, any one (or even both) application (main & splash) may still be in memory and when started again, it won't be the FirstTime so the splash won't show. This can be controlled with setting Splash_Done to False when UserClosed but the situation might arise that main app is still in while splash is out. What would Splash_Done be? The safest bet is to 'kill' both apps.
This safest bet will come at a price, namely doing the FirstTime all over again on next activation (even if otherwise the apps were still in memory). Depending on the main application this might be a large or small price to pay.
This concludes the basic structure of the main app.
The splash activity is fairly simple
in the create event we start the splash ONLY if it wasn't shown before.
you may ask, why not showing only on FirstTime? It's rather complicated for me to answer (B4A/Java/Android internals) but as i tested it (on the emulator) switching rapidly between portrait/landscape it crashed if it was shown on FirstTime.
Others, more expert than me, can explain that but my guess is that somehow the Splash_Stop sequence (see below) was called without the Splash_Show having a chance to initialize things (panel, timer...)
pressing BACK will cause the splash to stop and switch back to the main app.
finally we come to the Show & Stop sequences, and timer event
attached is a test project
My goal, right from the beginning, was to create a splash screen (welcome msg, logo, etc....) that I could "attach" to any application, hence my quest for as much "isolation" as possible between the 'real app' and the 'splash'. So Klaus, I took your idea of a 'main panel' to control visibility (from this thread) but i really didn't like having to deal with the main panel,layout or whatever in the tmr_tick event.
So i tried working with 2 activities, main & splash. That opened a can of worms as referred to by Jim Brown in this thread
I don't want to switch back and forth between 2 apps, just to show one app (splash) and 'forget' about it once it is finished and the main app is shown. Starting splash on firsttime else showing main panel is achieved by:
B4X:
If FirstTime Then
StartActivity(SplashMod)
Else
pnlMain.Visible = True
End If
but that will cause the pnlMain to be INVISIBLE after the splash.
So how to show it on the 1st time? (remember that i do NOT want to deal with pnlMain in the tmr_tick event of the splash!)
One solution is to make pnlMain visible even on FirstTime, like this:
B4X:
If FirstTime Then
StartActivity(SplashMod)
End If
pnlMain.Visible = True
but this will briefly show the main panel BEFORE the splash screen - not what i want
Another solution is to show it on resume:
B4X:
Sub Activity_Create(FirstTime As Boolean)
pnlMain.Initialize("")
Activity.AddView(pnlMain, 0, 0, 100%x, 100%y)
pnlMain.Visible = False
pnlMain.LoadLayout("somelayout")
If FirstTime Then
StartActivity(SplashMod)
Else
pnlMain.Visible = True
End If
End Sub
Sub Activity_Resume
pnlMain.Visible = True
End Sub
No good! Must read Erel's Activities Life Cycle again! Resume is called right after Create so this solution is basically just like the first one.
The real solution is to show pnlMain in Resume BUT CONDITIONALLY! Only after the splash has finished!
This is achieved with a semaphore that signals when the splash has finished.
B4X:
Sub Activity_Resume
If Splash_Done Then pnlMain.Visible = True
End Sub
The semaphore is declared in the splash activity (as much isolation!) process globals and is initialized and accessed in the main, so assuming the splash activity is called SplashMod, the resume code will have to be:
B4X:
Sub Activity_Resume
If SplashMod.Splash_Done Then pnlMain.Visible = True
End Sub
One more thing is left to deal with. When the user quits the main app with the back key, any one (or even both) application (main & splash) may still be in memory and when started again, it won't be the FirstTime so the splash won't show. This can be controlled with setting Splash_Done to False when UserClosed but the situation might arise that main app is still in while splash is out. What would Splash_Done be? The safest bet is to 'kill' both apps.
B4X:
Sub Activity_Pause (UserClosed As Boolean)
If UserClosed Then
ExitApplication
End If
End Sub
This safest bet will come at a price, namely doing the FirstTime all over again on next activation (even if otherwise the apps were still in memory). Depending on the main application this might be a large or small price to pay.
This concludes the basic structure of the main app.
The splash activity is fairly simple
B4X:
Sub Process_Globals
Dim Splash_Done As Boolean <==== the semaphore
Dim tmr As Timer <==== declared here to preserve it between pause/resume
End Sub
Sub Globals
Dim SplPan As Panel ' part of splash screen
Dim ivspl As ImageView ' part of splash screen
Dim lblspl As Label ' part of splash screen
End Sub
in the create event we start the splash ONLY if it wasn't shown before.
B4X:
Sub Activity_Create(FirstTime As Boolean)
If Not(Splash_Done) Then Splash_Show
End Sub
you may ask, why not showing only on FirstTime? It's rather complicated for me to answer (B4A/Java/Android internals) but as i tested it (on the emulator) switching rapidly between portrait/landscape it crashed if it was shown on FirstTime.
Others, more expert than me, can explain that but my guess is that somehow the Splash_Stop sequence (see below) was called without the Splash_Show having a chance to initialize things (panel, timer...)
pressing BACK will cause the splash to stop and switch back to the main app.
B4X:
Sub Activity_Pause (UserClosed As Boolean)
If UserClosed Then Splash_Stop
End Sub
finally we come to the Show & Stop sequences, and timer event
B4X:
Sub Splash_Show
If Splash_Done Then Return
activity.LoadLayout("splashpanel")
..... adjust panel...
tmr.Initialize("tmr",3000)
tmr.Enabled=True
End Sub
Sub Splash_Stop
splpan.Enabled=False
splpan.Visible=False
tmr.Enabled=False
Splash_Done=True
activity.Finish
StartActivity(Main)
End Sub
Sub tmr_Tick
Splash_Stop
End Sub
attached is a test project