Splash Screen for Android

When starting AndroidHarness there is a delay of a few seconds before the game is actually displayed (at least on the devices I’ve tried and it gets longer when nifty is starting as well). Is there any interest in creating a mechanism to display a splash screen to hide the time between the app starting and the display being shown? If there are no objections and some interest, I was going to try to implement it. I was thinking of trying to add a parameter to AndroidHarness to pass a picture filename that would be displayed until the app display was ready. Any thoughts?

http://hub.jmonkeyengine.org/groups/general-2/forum/topic/how-to-make-a-splash-screen/

I would use a nifty screen for this but the time I want to hide is the time to start the app and nifty. I want something similar to the startup screen in app settimgs but for android. Make sense?

Is this what are you talking about?







Yes. Doesn’t Android app show that when started?

No, Android does not show this screen while the app is starting. I would like to create it so that the screen is displayed initially and then disappears and shows the main game automatically when the app display is ready for display.

Just copy / paste the source code.

No, Android does not show this screen while the app is starting. I would like to create it so that the screen is displayed initially and then disappears and shows the main game automatically when the app display is ready for display.

Sorry. Last post was accidental. I’ll try to get something running.

I updated my app as you did with threading for the initiation of the game. I do not have Nifty yet. From what I can tell from the log, the splash screen displays 1.5 sec after the app is started and then the initial display of the app starts after another 1.5 sec (roughly).



I think I have a way to have the splash screen start immediately by changing the way “view” is attached to the activity layout, but it would require an engine change. Is that a possibility? If not, I won’t bother figuring out the details, but roughly, the idea is the following:

  • change the activity layout to have a framelayout that contains both the surfaceview created by AndroidHarness and a ImageView that is overlaid on top of the surfaceview
  • make the ImageView full screen to hide the SurfaceView
  • have a callback from the context to AndroidHarness to remove or hide the ImageView when the app initialization is done (ie. just before simpleUpdate is called the first time



    I think it can all be done within AndroidHarness except for the callback. I’m not sure where that would come from, maybe the Android specific OGLESContext (that’s where the SurfaceView Renderer code is).



    Would that be a completely bad idea from an engine standpoint?

I Have this “issue” too, the problem is that we can’t really use Nifty for this because loading a simple screen with just text takes around 6 seconds with my tablet…



I’ll look into this and i’ll try to find a general solution.

ok so i followed this tutorial

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:loading_screen?s[]=loading

I chose the multithreaded way (last example) and instead of using nifty and the progress bar i used a simple quad with a splash screen.

[java]

public class MyApp extends SimpleApplication {



private Picture splash = new Picture(“splash”);





public void simpleInitApp() {

setDisplayStatView(false);

setDisplayFps(false);



float size = Math.min(cam.getWidth(), cam.getHeight());

splash.setHeight(size);

splash.setWidth(size);

splash.setImage(assetManager, “Interface/RPGMapper.jpg”, false);

splash.setLocalTranslation(cam.getWidth() / 2f - size / 2f, 0, 0);

guiNode.attachChild(splash);

}









public void simpleUpdate(float tpf) {

if (load) {

if (loadFuture == null) {

loadFuture = exec.submit(loadingCallable);

}

if (loadFuture.isDone()) {

splash.removeFromParent();

load = false;

}

}

}

[/java]



and of course the “loadingCallable” where all the initialization takes place.



The splash screen load fairly quickly and is displayed while the rest of the assets are loading.

1 Like

Did you all deactivate niftys excessive logging on android? Logging can bog down the performance on android immensely.

How fast is faily quickly? I was thinking to hide the time it takes for the first update loop to run (ie. the time from AndroidHarness to the first call of simpleUpdate in the app). Even without Nifty, I think it takes 3-4 sec for my display to show up after starting the app but I’m not doing any multi-tasking to initialize anything.

@normen said:
Did you all deactivate niftys excessive logging on android? Logging can bog down the performance on android immensely.

Yeah i did, it's not logging.

@iwgeric said:
I updated my app as you did with threading for the initiation of the game. I do not have Nifty yet. From what I can tell from the log, the splash screen displays 1.5 sec after the app is started and then the initial display of the app starts after another 1.5 sec (roughly).

I think I have a way to have the splash screen start immediately by changing the way "view" is attached to the activity layout, but it would require an engine change. Is that a possibility? If not, I won't bother figuring out the details, but roughly, the idea is the following:
- change the activity layout to have a framelayout that contains both the surfaceview created by AndroidHarness and a ImageView that is overlaid on top of the surfaceview
- make the ImageView full screen to hide the SurfaceView
- have a callback from the context to AndroidHarness to remove or hide the ImageView when the app initialization is done (ie. just before simpleUpdate is called the first time

I think it can all be done within AndroidHarness except for the callback. I'm not sure where that would come from, maybe the Android specific OGLESContext (that's where the SurfaceView Renderer code is).

Would that be a completely bad idea from an engine standpoint?

I did that at first, but you gain like 0.2 seconds...IMO it does not worth the effort of a listener to notify the view that the game is loaded.

I have similar times than you, 1.5 sec before something appear. My game though takes around 13 seconds to load.

When I create the ImageView in my Activity and overlay it on top of the SurfaceView, the image shows up immediately, then is dismissed on the first simpleUpdate loop. There is no delay between the app starting and the splash screen display showing. Then after 3 seconds, the splash screen is turned invisible (and removed from the layout) and the app display is shown.



Below is rough code (very rough):



Main Activity:

[java]

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);



((Main) app).setAndroidListener(this);



showSplash = true;

if (showSplash) {

frame = new FrameLayout(this);

setContentView(frame);

frame.addView(view);

img = new ImageView(this);

img.setImageResource(R.drawable.monkey);

WindowManager wind = this.getWindowManager();

Display disp = wind.getDefaultDisplay();

FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(

FrameLayout.LayoutParams.FILL_PARENT,

FrameLayout.LayoutParams.FILL_PARENT

);

frame.addView(img, disp.getWidth(), disp.getHeight());

} else {

setContentView(view);

}



}



public void onUpdate(float tpf) {

if (showSplash) {

this.runOnUiThread(new Runnable() {

@Override

public void run() {

img.setVisibility(View.INVISIBLE);

frame.removeView(img);

}

});

showSplash = false;

}

}



[/java]



Main Game Class:

[java]

@Override

public void simpleUpdate(float tpf) {

if (firstUpdate) {

if (androidListener != null) {

androidListener.onUpdate(tpf);

logger.log(Level.INFO, "Calling onUpdate");

}

}

firstUpdate = false;

}



[/java]

1 Like

I’ll test it tonight, what bothers me the most is the callback in the simple update…

Would it be better if the initial display was inside AndroidHarness.java and the dismissal in OGLESContext.java? Or is that the same issue? Not sure if what bothers you is the fact that the user need to put a callback to Android in a non-Android area, or having a callback in the update loop? If the display has handled in AndroidHarness itself and OGLESContext, the main game code (class extending SimpleApplication) would not be Android specific.

Yes

@iwgeric said:

Not sure if what bothers you is the fact that the user need to put a callback to Android in a non-Android area


Yep that's it, what even bothers me is that the user HAS to do it...
The neat thing would be that the user overrides in his mainActivity lest say a splashScreenResource variable, and bang....splash screen.
Putting the callback in the context may be a good idea

Do you want me to see if I can screw it into AndroidHarness with a variable for the image filename (or Resource ID value) and then create a callback inside the context to remove it? Maybe the first time onDrawFrame is run inside the “if (renderable.get())” area of onDrawFrame?

1 Like

yeah, if you’re warm to get into this, i won’t stop you :wink: