Android Development

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

  • Share/Bookmark
:, , , ,

21 Comments for this entry

  • johnse

    Awesome website, really useful stuff

  • Jim

    Simple but helpfull :)

  • sherlockhua

    thanks for good article

  • tony

    That is pretty easy but so smart!!!

    Very useful.

  • Monu

    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.

  • Kevin

    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.

  • Martin

    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!

  • Kevin

    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:

    1
    2
    3
    
    if (continueOn) {
        startActivity(new Intent("org.droidmpc.DroidMPC"));
    }

    and then added:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
      // TODO Auto-generated method stub
      if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_SEARCH || keyCode == KeyEvent.KEYCODE_HOME){
        continueOn = false; _active =false;
      }
     
      return super.onKeyDown(keyCode, event);
    }

    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.

  • Kevin

    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.

  • Martin

    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!

  • Raghavendra

    Hi Martin,

    Thanks for your post. It is useful.

  • AndrĂ©

    Instead of using a new thread you could simply instantiate a Handler object and use the postDelayed() method like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.splash);
      new Handler().postDelayed(new Runnable(){
          @Override
          public void run() {
            finish();
            startActivity(new Intent("com.droidnova.android.splashscreen.MyApp"));
          }
      }, _splashTime);
    }
  • Martin

    Thats right, but I cant stop the SplashScreen with an input from the user like a tap.

  • Extreme

    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 ?

  • Martin

    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:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.droidnova.android"
          android:versionCode="1"
          android:versionName="1.0">
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name=".SplashScreen"
                      android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".MyApp">
                <intent-filter>
                    <action android:name="com.droidnova.android.splashscreen.MyApp" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>
        </application>
        <uses-sdk android:minSdkVersion="4" />
    </manifest>

    Please post what you do and post the stack from LogCat, so I can take a closer look and maybe reproduce the issue.

  • ExtremeT

    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.

  • Sunny

    Hi
    Nice website. Any idea about how Android application will be used accessing db server and show product information?

  • Martin

    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.

  • Kiran PMS

    Thank you Martin. it is very helpful.

  • Nithin

    Thank you Martin. Your tutorial helped a lot

Leave a Reply