1

I have an application which utilizes a splash screen and a choice screen, as depicted in the following manifest:

<application
    android:name="com.example.CoolApp"
    android:label="@string/app_name"
    android:icon="@drawable/app_icon_debug"
    android:theme="@style/Theme.NoBackground">
    <activity
        android:name="com.example.Splash"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:noHistory="true"
        android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>

        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="coolappscheme"/>
        </intent-filter>

    </activity>
    <activity
        android:name="com.example.ChoiceActivity"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateHidden"/>
</application>

The splash screen shows for about 2 seconds, and then navigates to the ChoiceActivity via the following code:

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

  ... some stuff for showing the Splash screen ...

  Thread mythread = new Thread() {
    @Override
    public void run() {
      try {
        .. animation stuff for fading in ...

        while (splashActive && ms < splashTime) {
          if(!paused)
            ms=ms+100;
          sleep(100);
        }
      } catch(Exception e) {
      } finally {
        Intent intent = new Intent(Splash.this, ChoiceActivity.class);
        startActivity(intent);
      }
    }
  };

Now, clearly there are a number of things wrong with this code (starting with why the author decided to use a separate Thread instead of an AsyncTask. However, putting that stuff aside for the moment, if the user performs the following actions:

  1. Launch the application & see the splash screen.
  2. Force the application into the background (e.g. the user receives a phone call, or maybe just hits the 'home' button).

Then, when the Thread completes (i.e. the finally block is reached and the Intent is created), the new ChoiceActivity is created, but it also brings the application to the foreground. I want to disable this behavior. That is, I want the activity to be loaded, but the application to remain in the background. If that's not possible, then I want the application to delay loading of the new Activity (//any// new Activity) until after the Application has been resumed.

How can I achieve this?

jwir3
  • 6,019
  • 5
  • 47
  • 92

1 Answers1

1

Activities are meant to run in foreground..There is a given lifecycle which is based on how the user interacts with the app. Therefore you actually shouldn't be trying to "start your activity in background", because it does not make sense..What you can do though is somehow alter how the activity reacts on events from outside of it.. You can for example create a new boolean field in your activity and set it to false everytime in onPause() and to true in onResume()...

You could then check for it when starting the new activity and actually only start it when true. Otherwise just set the field to true and then in onResume() start the activity when the field would be true..

Also you should take in account, that background activity could be killed by the system at any time. Activity should deallocate all system resources and stop it's work when it goes to background..Only then you can be sure your app won't go into an unpredictable state.. For background tasks you should go with services, which are basically "activities without UI" (I don't believe I've said that) - parts of your app running in the background.

simekadam
  • 7,334
  • 11
  • 56
  • 79
  • Well, that's an obvious solution. I'm trying to determine why the Android documentation seems to indicate that this shouldn't happen, yet it does. It's unlikely, IMHO, that every Android app maintains these internal flags to make sure every Activity isn't in the background before launching a new Activity. – jwir3 Feb 21 '14 at 21:23
  • why would an app launch an activity in background? that does not make sense.. no other apps really don't have to do that..if you launch an activity you probably want to show it to the user..it just what activities are made for – simekadam Feb 21 '14 at 21:26
  • Well, for one instance, if the application is interrupted while loading an activity (e.g. the user taking a phone call or deciding that the application wasn't the one they wanted to launch). – jwir3 Feb 21 '14 at 21:27
  • I maybe gave the wrong example from our codebase. There are instances where we use `AsyncTask` to do some processing, and the `AsyncTask` launches an Activity upon completion. The user might want to suspend the application while the processing is happening, though, for reasons I mentioned in my comment above. – jwir3 Feb 21 '14 at 21:29
  • 2
    you should read about activity lifecycle..http://developer.android.com/training/basics/activity-lifecycle/index.html when your app gets paused, i.e. when it goes to background then you should actually stop what it is doing..because the system can destroy it completely at any time when in background.. Activity is not intented to do any stuff in background..that's what services are made for. – simekadam Feb 21 '14 at 21:32
  • ...if you want to have such thing there, just add the foreground check as I originally posted..it's a bit clumsy, but that's because it's actually a non-standard behavior.. you can read a lot about background/foreground detection in this ultimate answer;) http://stackoverflow.com/a/5862048/419449 – simekadam Feb 21 '14 at 21:37
  • Could you tell me why the downvote? How did you solve your issue in the end? – simekadam Feb 22 '14 at 12:46
  • I downvoted this answer because "You really shouldn't use such meaningless splashscreen and you really shouldn't do it this way (sleeping thread)" was opinion, and I didn't find it helpful to the overall discussion. If you edit your answer, though, to remove this line, and add in that when an activity is in the background it can be killed at any time (i.e. your explanation in a previous comment), I'll re-upvote it and accept it as the answer. – jwir3 Feb 24 '14 at 15:18
  • :) ok..I've altered the answer a little bit..but basically it holds:) you shouldn't to it this way..use postDelayed() method on a Handler, or call an Intent via AlarmManager instead.. – simekadam Feb 24 '14 at 15:29