All is well in the Splash Screen business

boten

Active Member
Licensed User
Longtime User
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:

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
 

Attachments

  • spl2apps_demo.zip
    61 KB · Views: 464

nfordbscndrd

Well-Known Member
Licensed User
Longtime User
Using ExitApplication only if the user presses the Back button didn't make sense to me because AFAIK, pressing the Back button has the same effect as rotating the orientation of a device or pressing Home and having the OS kill the app to free up memory to run other app(s) -- when the user resumes the app, Create will run again with FirstTime=False followed by Resume running.

So I ran the example you provided and I the get same results from all 3 of these interruptions whether ExitApplication is used or is commented out -- the splash screen is not showing again.

Can you explain what ExitApplication does for you? In your original post, you said "The safest bet is to 'kill' both apps", but did you ever see any effect from NOT doing it?

(I ask because if I'm wrong about how this stuff works, I need to revise the Activity_Create, Pause and Resume section in the Documentation Wiki.)
 
Upvote 0

boten

Active Member
Licensed User
Longtime User
well, you are right saying that when you comment out ExitApplication the splash is NOT showing again. But my pupose was that in such a case (BACK button) it WILL show again.

Trying to equate the behaviour of the program to the familiar (to me, at least) Windows system I figure that:

1. Screen orientaion change is "equivalent" to window resize

2. pressing Home is "equivalent" to showing the desktop or in the case of Home & doing other app will be "equivalent" to switching to another pgm on the taskbar.

3. pressing BACK is "equivalent" to closing the progam (either by using its Exit menu or by clicking the X in the corner).

Usually when you run a Windows program, its splash screen appears every time it is run again, but does not appear on window resize, showing the desktop, switching to other program and then switching back to the app. It is that same behaviour that i want to mimick. To me, if the user press BACK he wants OUT OF THE APPLICATION. If he rotates the screen or press Home he wants to do something else but "intend" to return to the program.

Hope this clears my goal.

As for the behaviour of ExitApplication & FirstTime, I relied on Erel's answer in the above mention thread (see here)
 
Last edited:
Upvote 0

boten

Active Member
Licensed User
Longtime User
Man, you had me scared. I tested & re-tested the project b4 posting it here, making sure everything works the way i wanted it to. Then u came, putting doubt in my mind because i tested it ONLY on the emulator. Maybe it won't work as expected on a real device, so i connected my phone and ran my app on it. Lo and behold, it works like charm on the phone too. So i'm afraid i don't know what happens when u run it, but on my phone rotating the screen, pressing home and launching other apps and then launch my app again will not bring the splash screen, BUT quitting it with the back key and then running it again DOES show the splash.
 
Last edited:
Upvote 0
Top