How to create a Splash Activity - best practices

In this small tutorial, I will explain how to add 2 types of splash activities in Android:

  1. Splash that shows a simple layout
  2. Splash that plays a movie


While working on different projects, I discovered that splash activities are really simple to create. You just create some xml layout for your activity, create the activity, and set a timer after a couple of seconds with a Runnable that starts another activity.



However, I have introduced a small feature that complicates things. I think we all agree that users prefer to have the ability to skip the splash screen. Since we're dealing with customers having eyes and users having taste, we can not add a skip button. Instead, I think it would be best that a splash is skipped when the user touches the screen.

Before coding, what is the major complication? Well, we do not want the splash to hang there if the user does not touch the screen so we still need the timer to start the second activity. Yet, we want the splash activity to start this second activity also when the screen is touched. The problem might happen when the user touches the screen and the timer is fired also: You will have 2 instances of the second activity on the stack - a really undesirable effect.

Solution: When I first did this, I used to complicate my life with some synchronization because it felt like there was always a situation where a user can start the second activity twice, either by tapping the screen multiple times or because of the timer being run even after skipping it. However, it was pretty simple, in all our splash activities, we should add the following piece of code before using any of the flavors of startActivity:

if(isFinishing())
 return;

This code will work perfectly knowing that you will finish the Splash when you start the second activity. Anyway, in this tutorial, I will explain how to add this "skip" feature very easily but it is up to you to add it.


Splash Activity that shows a simple layout
  1. Create a new Android project if you've not already done so
  2. Create two Activities: SplashActivity.java and MainActivity.java in your src directory - (keep in mind that sometimes MainActivity is created automatically for you: it will be our second activity)
  3. Fix your manifest to start the SplashActivity first:

  4. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="mobi.sherif.splash"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="15" />
    
        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".SplashActivity"
                android:label="@string/title_activity_main" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name=".MainActivity"
                android:label="@string/title_activity_main" >
            </activity>
        </application>
    
    </manifest>
    

  5. Create your MainActivity as you wish...
  6. In SplashActivity.java, Create the jump function that will jump to the second activity

  7. private void jump() {
    //it is safe to use this code even if you
    //do not intend to allow users to skip the splash
    if(isFinishing())
      return;
     startActivity(new Intent(this, MainActivity.class));
     finish();
    }
    

  8. If you do not want to allow skipping, You, yourself, should skip this step and go to step 7.
    In SplashActivity.java, override the onTouchEvent(MotionEvent) function using the following code:

  9. @Override
    public boolean onTouchEvent(MotionEvent event) {
     jump();
     return true;
    }
    

    However, Please keep in mind that you can allow users to skip the activity by using on click listeners or any other manner, just by calling jump()

  10. If you wish to show a movie, jump to the Splash Activity that plays a movie instead.
    Add to your res/layout folder a new xml file and call it activity_splash.xml This will be the layout of the SplashActivity. Here is a sample:

  11. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <TextView
            android:id="@+id/textsplash"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:padding="@dimen/padding_medium"
            android:text="This is my Splash Screen" />
    
    </RelativeLayout>
    

  12. In SplashActivity.java, override the onCreate(Bundle) method and set the content view to the xml layout that you just created in step 7:

  13. @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
    

  14. Now add three members to your class (under the line public class SplashActivity extends Activity):

  15. private static final long SPLASH_TIME = 3000; //3 seconds
    Handler mHandler;
    Runnable mJumpRunnable;

    SPLASH_TIME: this is how long the splash will appear in milliseconds
    mHandler: this a handler that we can use to execute some code after some time
    mJumpRunnable: this a the runnable that will be executed after the time passes (we will probably just call jump() in this runnable)

  16. Finally, lets fix the onCreate(Bundle) method to instantiate this handler and post this runnable:

  17. @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        mJumpRunnable = new Runnable() {
      
      public void run() {
       jump();
      }
     };
        mHandler = new Handler();
        mHandler.postDelayed(mJumpRunnable, SPLASH_TIME);
    }
    

    Here, we first instantiated the Runnable and as you may have noticed, the run() function just has one line with a call to the jump() method.
    We used the postDelayed(Runnable, long) method of the Handler to ask it to execute this Runnable after SPLASH_TIME passes.

    This concludes it. Once you run this, it will show up a screen that will be dismissed after 3 seconds.

    here is a sample project with a splash that uses a normal layout
Splash Activity that plays a movie

Do the first 6 steps of the Splash Activity that shows a simple layout and continue here with step 7:

  1. Add to your res/raw folder your movie (preferably an mp4 movie!) If you do not have a raw folder there, just create one. I will consider that it is called splash.mp4 (here is a sample mp4 splash)
  2. In SplashActivity.java, override the onCreate(Bundle) method to play this video in this way:

  3. @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     try{
             VideoView videoHolder = new VideoView(this);
      setContentView(videoHolder);
      Uri video = Uri.parse("android.resource://" + getPackageName() + "/"
        + R.raw.splash);
      videoHolder.setVideoURI(video);
      
      videoHolder.setOnCompletionListener(new OnCompletionListener() {
    
       public void onCompletion(MediaPlayer mp) {
        jump();
       }
       
      });
      videoHolder.start();
     } catch(Exception ex) {
      jump();
     }
    }
    
    As discussed in one of my posts, How to play video from resources, this is a good way of playing a video. We set the content view to a VideoView, which we give the movie that we previously added to the project.
    Two things are important: First, we need to use the setOnCompletionListener method of this VideoView and we set the OnCompletionListener to call our jump() function. Last but not least, we need to include all this code in a try...catch block and call jump() if an exception is thrown for some reason (we do not want a user stuck on the splash screen).

    here is a sample project with a splash that plays a movie

8 comments:

  1. I'd suggest some screen shots ;)
    Nice work

    ReplyDelete
  2. Thanksssssss!!! I love the onTouchEvent Part ;)!!!

    ReplyDelete
  3. Thanks! Helped me a lot.

    ReplyDelete
  4. thanks a lot ....em eager to have
    like that

    ReplyDelete
  5. Quero agradecer antes de tudo pois este post me ajudou muito. E queria também deixar minha dúvida, como deixar o reprodução do video em Fullscreen?
    Nesse caso o video reproduz apenas no topo da tela deixando exatamente a outra metade sem nada na visualização, queria um método de deixá-lo em modo fullscreen ou que fique alinhado no centro da tela!

    Vlww pela ajuda
    Like

    ReplyDelete
  6. Quero agradecer antes de tudo pois este post me ajudou muito. E queria também deixar minha dúvida, como deixar o reprodução do video em Fullscreen?
    Nesse caso o video reproduz apenas no topo da tela deixando exatamente a outra metade sem nada na visualização, queria um método de deixá-lo em modo fullscreen ou que fique alinhado no centro da tela!

    Vlww pela ajuda
    Like

    ReplyDelete
  7. Bom dia diogo alves!! eu tbm to com a mesma duvida do video q ele reproduze so na mitade da tela...vc consegueu resolver ?? se compartilhar a solucao eu agradeco vui vlw

    ReplyDelete