How to: Create a splash screen
by Martin on Oct.14, 2009, under how to
Many Applications, mostly games, on the market show splash screens. With this screen they prompt a logo for the application and/or the author.
I will show you a short way to implement a splash screen which will occur on every startup, will stay for a number of seconds you can define, will close on touching the screen and will not reappear on pressing the back button.
I created an empty project named SplashScreen with the activity SplashScreen. This activity will display the splash screen, so we have to create a new activity which will be the first real view you want to display. In my case this activity is named MyApp.
To see, that we see different screens, we copy the content of our layout file main.xml and paste it into a new layout file called splash.xml. Of course we have to change the @string/hello reference to a now one.
To make it short, here the string.xml, the main.xml and the splash.xml
string.xml
1 2 3 4 5 6 | <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">SplashScreen</string> <string name="main_screen">MainScreen</string> <string name="splash_screen">SplashScreen</string> </resources> |
main.xml
1 2 3 4 5 6 7 8 9 10 11 12 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/main_screen" /> </LinearLayout> |
splash.xml
1 2 3 4 5 6 7 8 9 10 11 12 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/splash_screen" /> </LinearLayout> |
The layouts aren’t beauty but thats not the intention of this how to.
The activity MyApp is really nothing more than a new created activity.
1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.droidnova.android; import android.app.Activity; import android.os.Bundle; public class MyApp extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } } |
But now lets go to the more interesting part: the SplashScreen activity itself.
We will work with a thread to realize the function, that the screen will disappear after some seconds. For that we need two class variables. One for the number of time the screen has to appear and the flag, if the thread should run or not.
1 2 | protected boolean _active = true; protected int _splashTime = 5000; // time to display the splash screen in ms |
In the onCreate() method, we will create a Thread object and override the run() method dynamically.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.splash); // thread for displaying the SplashScreen Thread splashTread = new Thread() { @Override public void run() { try { int waited = 0; while(_active && (waited < _splashTime)) { sleep(100); if(_active) { waited += 100; } } } catch(InterruptedException e) { // do nothing } finally { finish(); startActivity(new Intent("com.droidnova.android.splashscreen.MyApp")); stop(); } } }; splashTread.start(); } |
As you see from line 13 – 18, we run in a while loop if our flag is true and if our waited variable is less the number we defined in our variable _splashTime.
Finally, we finish our activity, which prevents the restart with the back button, start a new activity which will start our MyApp activity and the last step should be to stop the thread.
At the end we override the function onTouchEvent() and set the _active flag to false to force the thread to stop the while loop and start the MyApp activity immediately.
1 2 3 4 5 6 7 | @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { _active = false; } return true; } |
Thats it!
Full Eclipse project: SplashScreen.zip
October 14th, 2009 on 4:24 pm
Hi. Useful post.
October 18th, 2009 on 3:18 pm
Awesome website, really useful stuff
October 19th, 2009 on 9:08 am
Simple but helpfull
October 20th, 2009 on 4:19 am
thanks for good article
October 28th, 2009 on 1:54 pm
That is pretty easy but so smart!!!
Very useful.
November 18th, 2009 on 8:54 am
Congratulations on your tutorial! It is very helpful indeed.
I have a question. Why have you called stop() method on your thread? I think, the method has been deprecated and your code does not actually need it since, your thread would have actually finished executing the run method.
November 20th, 2009 on 7:42 am
Question.. the finish() is done why? It says that when you call this method it returns control to the previous activity that started this one. If this is the MAIN activity.. does it return control back to the previous app that was running before the user started this app.. or maybe the home screen?
Also, at least in the emulator, if I hit the back button while the splash screen is up, it takes me back to the home screen.. but then the splash finishes and my next activity starts without me touching anything. How do you stop the splash if the home/back is pressed? You certainly don’t want someone to have the app continue to run once the splash is done.. ideally we want a way to stop the splash and the app.. exit it, if the back/home are pressed during the splash screen.
I see this as a major issue with most apps today on android phones.. too many apps continue to run in the background, some not pausing correctly and draining the battery. It seems to me if you hit back/home during the main screen or splash, the app should completely exit, cleaning up properly. The only time I’d consider a game, or most apps to “pause” and later resume is if it is in the middle of doing something.
Thanks.
November 20th, 2009 on 12:07 pm
finish() is nothing more than a method, it will be executed but the startActivity() will be called. So after the Splash Screen I am sure that my app is started and the Splash Screen is completely stopped.
Anyway your right, if you hit the back button on the Splash Screen, you reach the home screen and the app will be started right away. Thats because of the finally block.
Change that or simply catch the press of the back button and everything is fine.
One thing for you to understand: My tutorials aren’t designed to be the perfect solution. They are for you to show you the way and the possibilities, but how you do it in the end should always be your decision. Never use a snippet of code you don’t understand completely!
November 21st, 2009 on 7:20 pm
Absolutely right Martin. Great reply. I thank you for your tutorials, I am still a total android newb. I understand the lifecycle very well and how the android architecture functions. Just getting up to speed with the different ways of doing things compared to say Swing apps and such. I actually added a boolean to your code and catch the back and home buttons. Even tho home ALWAYS goes home and there is no way to stop it like you can with back/menu/search, it still executes the handler for it. So I set a boolean that is checked in the finally:
and then added:
Sorry..not sure how to “block” the code in my response so it may look unformatted. Anyway, this worked.. at least for the most part. I sometimes seem to get the app stuck if I press the home or back button too fast.. or perhaps right as the splash is about to be done.. not sure why but it seems to work for the most part.
I find it interesting that an app could do what your splash does..that is, you go back, and while the app still runs in the background, can take over the screen again without the user pressing anything. That is definitely different style of device programming than say iPhone and other devices. On the droid forums I’ve stated that I think this is going to be one of the challenges of fly-by-night android developers.. they’ve got to learn to use all the lifecycle events on all activities/views properly to avoid situations like this, or their app running in the background eating up battery without the end user knowing it. This also may be the biggest issue most non-techie people that buy android phones will complain about.. why is such and such app still running (after they figure out that it even is an app) and then they may get scared when they are told “install Task killer and after you are done, run task killer and kill it”. I think Google needs to find a better way of enforcing that apps either shut down, or really teaching developers that they should generally catch back/home/etc buttons and IF like in a game they don’t need to run any more, kill it. Don’t keep it around.
Anyway, again, thank you, I will be reading/following more of your tutorials.
November 28th, 2009 on 8:20 am
Hey.. one thing I wanted to add to this tutorial for anyone that reads this.. I was constantly getting a Force Closed issue not understanding why. In the android manifest, you define two activites, one for the splash, one for the launcher to run after the splash closes.
In this above example, you see the code:
startActivity(new Intent(“com.droidnova.android.splashscreen.MyApp”));
In order for that to actually work, you need to make sure to have the following in your android manifest, otherwise you’ll see a force close dialog.
I am not quite sure I understand enough of android to know why this is needed. I didn’t have the in my activity declaration, and the code to try to launch it causes the force close issue.
November 28th, 2009 on 3:23 pm
It seems your code was stripped. Please send it to me in an email at [info at droidnova dot com] and I will edit your comment for you!
Thank you!
December 14th, 2009 on 10:51 am
Hi Martin,
Thanks for your post. It is useful.
January 1st, 2010 on 2:43 pm
Instead of using a new thread you could simply instantiate a Handler object and use the postDelayed() method like this:
January 1st, 2010 on 3:31 pm
Thats right, but I cant stop the SplashScreen with an input from the user like a tap.
January 13th, 2010 on 11:08 pm
I’m actually curious as to what Kevin was saying to add to the manifest to stop the force closes. That’s exactly what I’m having an issue with. Been trying to figure out the properly intent to use in the manifest but so far nothing has worked.
Any ideas ?
January 14th, 2010 on 1:26 pm
I am not sure why some of you have an FC issue, but the uploaded Manifest is exactly the same I just used to test.
Here is it again:
Please post what you do and post the stack from LogCat, so I can take a closer look and maybe reproduce the issue.
January 16th, 2010 on 6:18 pm
I figured out what the problem was. I’m not sure if this was my mistake or perhaps just a coding issue/sdk type thing.
In the SplashScreen.java file this line:
startActivity(new Intent(“com.droidnova.android.splashscreen.MyApp”));
had to be changed to this:
Intent intent = new Intent(); intent.setClass(SplashScreen.this, whatever.class);
startActivity(intent);
That fixed the force closing issue, at least for me.
January 18th, 2010 on 4:18 am
Hi
Nice website. Any idea about how Android application will be used accessing db server and show product information?
January 18th, 2010 on 9:32 am
Well, its not the right topic for this question, but it should be easy, if you have a frontend for you database server, which you can access by HttpRequest or SOAP or REST.
January 19th, 2010 on 1:25 pm
Thank you Martin. it is very helpful.
January 28th, 2010 on 5:19 pm
Thank you Martin. Your tutorial helped a lot