21

Currently we have a splash screen that is displayed in our app. However, if there is no data to be gathered or processed that is waiting, we'd like to go straight into our first activity. Is there a way to do that without having the splash screen flash?

The AndroidManifest.XML of the splashscreen portion is as follows:

<activity android:name="com.example.SplashScreenActivity"
        android:label="@string/app_name"
        android:noHistory="true" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
StackOverflowed
  • 5,854
  • 9
  • 55
  • 119

4 Answers4

27

What I have done successfully in the past is to create an invisible activity as the main activity. It never gets shown to the user, because it launches the "correct" activity in the constructor.

For this reason, there is no need to theme the activity as "invisible" as it does not load a view.

Inside I place some logic which determines which activity to show to the user first. This works perfectly for my use case - give it a try.


Manifest Declaration (note the noHistory="true" parameter):

    <activity
        android:name=".activity.EntryActivity"
        android:noHistory="true" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

EntryActivity class:

public class EntryActivity extends Activity 
{ 

    @Override
    public void onCreate(Bundle savedInstanceState) 
    { 
        super.onCreate(savedInstanceState); 

        // launch a different activity 
        Intent launchIntent = new Intent(); 
        Class<?> launchActivity; 
        try
        { 
            String className = getScreenClassName(); 
            launchActivity = Class.forName(className); 
        } 
        catch (ClassNotFoundException e) 
        { 
            launchActivity = DefaultHomeActivity.class; 
        } 
        launchIntent.setClass(getApplicationContext(), launchActivity); 
        startActivity(launchIntent); 

        finish(); 
    } 

    /** return Class name of Activity to show **/
    private String getScreenClassName() 
    {       
        // NOTE - Place logic here to determine which screen to show next
        // Default is used in this demo code
        String activity = DefaultHomeActivity.class.getName(); 
        return activity; 
    } 

} 
Community
  • 1
  • 1
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
  • What's the purpose of `android:launchMode="singleInstance"` in this case? When I include that, none of the subsequent activities in my app show up in the history (my app isn't present in the Recent Apps list). When I exclude that line, however, everything seems to work as expected. – jokeefe Jan 03 '14 at 01:03
  • 1
    @jokeefe IIRC this is part of the production code I left in when I ripped it out to answer the question. I think you are right - it is not needed to answer the question. In my case it had to do with the different ways this `EntryActivity` was launched... – Richard Le Mesurier Jan 03 '14 at 14:58
  • Oh good. I was hoping I wasn't overlooking something. Thank you for getting back to me! – jokeefe Jan 03 '14 at 18:13
2

Given that the launcher will start the activity you specify in your Manifest, it's not possible to set conditions on whether that activity will be started (or another).

So you're left with the options as Richard Le Mesurier and dors suggest:

  1. Start the main Activity, then launch the Splash Activity if needed
  2. Start a gui-less Activity (no layout file), then decide which Activity should be presented to the user

I'd prefer the second option, or if you're planning to introduce Fragments anyway, use them here:

  1. Use Fragments. Start your main activity, which has a Fragment placeholder. If you need to show Splash Screen, load the SplashScreenFragment in that activity, otherwise, load the Fragment that constitutes the first useful screen to the user.

As an aside, the use of splash screens is discouraged; as a user, I'd prefer to see the main Activity with most of the static UI components loaded immediately, and some on-screen indication that something is loading/updating.

ataulm
  • 15,195
  • 7
  • 50
  • 92
1

afaik you can only have 1 main activity.

What I did when I had this issue is always start the main activity (not splash), and in its onCreate() method I would start the splash screen if needed.

Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
dors
  • 5,802
  • 8
  • 45
  • 71
  • That's unfortunate if that's the case. The problem is, we could start with the Splash Screen, the Main Activity or the Login Activity if the user is not already logged in, so there's no "central" activity. – StackOverflowed Jul 04 '13 at 16:34
  • It's not that bad... I think you should make the one the user's will see the most your main activity, and make a few checks in its onCreate – dors Jul 04 '13 at 16:36
1

You can do something like this:

  1. Your Splash Screen is the main activity (Launcher-Category)
  2. If your splash screen can load data (or whatever your splashscreen does), do it. After finished, close the spalsh screen (call finish()) and start the real first activity and pass the data as intent extra.
  3. If your splashscreen can not load data or (or whatever your splashscreen does), start the next Activity by using an Intent and finish the spalsh screen activity by calling finish()

So the workflow of your app will be:

  1. Click on the launcher icon
  2. The Splash Screen Activity will always been started
  3. If spalsh screen can not load, than the activity will be finished immediately and the other activity will be started. Your app user will not notice that the splash screen activity if you finish() the splash screen activity immediately, because the activity is never shown on screen in this case
sockeqwe
  • 15,574
  • 24
  • 88
  • 144