Haakon
Haakon

Reputation: 295

Determining if app is running in background

How can I tell that my application has been put in the background (i.e. none of my app's activities are visible anymore)? I need to determine this so that I can release resources shared among several of my activities (graphics, sound clips and a socket connection).

I've thought about keeping a global counter that's incremented in the activities' onStart() method, and decremented in onStop(). If the counter reaches zero, then all activities have been stopped and my app is running in the background. However I'm not sure if this is going to be 100% reliable. Also, I can't help but think that there must be a better way of doing this.

Upvotes: 3

Views: 2240

Answers (5)

Dan J
Dan J

Reputation: 25673

I haven't tried this myself yet, but I think the following would work.

  • Create your own custom Activity class that extends Activity (as suggested in this SO question).
  • Ensure all your activites extend your custom Activity class.
  • @Override the onStop() method (as per the Activity life cycle docs).
  • Have onStop() call the utility method below (code based on Droid-Fu project) to figure out if your app is now in the background.

My worry is there could be some timing windows when your last activity closes before its new activity (also i your app) launches, but hopefully that is avoidable.

public static boolean isApplicationInBackground(Context context) 
{
    ActivityManager am = 
      (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

    List<RunningTaskInfo> tasks = am.getRunningTasks(1);

    if (!tasks.isEmpty()) 
    {
        ComponentName topActivity = tasks.get(0).topActivity;

        if (!topActivity.getPackageName().equals(context.getPackageName())) 
        {
            return true;
        }
    }

    return false;
}

Let us know how you get on as I might need to implement this feature too!

Update: I've done some quick testing of this code.

It seems to work fine when pressing the home key to exit the application, as the running task changes to ComponentInfo{com.motorola.blur.home/com.motorola.blur.home.HomeActivity} on my device. However, the code doesn't detect the app as in the background when using the back button to exit the application (it still thinks my app is running).

This scenario can be detected by overriding onDestroy() in your top level activities, and checking isFinished() to confirm that the app is getting destroyed (rather than the activity being recreated, e.g. for an orientation change).

Upvotes: 0

user433825
user433825

Reputation:

You shouldn't need to know this, but to answer you:

in your main activity:

public boolean inBackground;

@Override
public void onPause()
{
     inBackground=true;
     super.onPause();
}

@Override
public void onResume()
{
     inBackground=false;
     super.onResume();
}

Upvotes: 2

Mojo Risin
Mojo Risin

Reputation: 8142

If you need this functionality maybe your architecture is not well designed. Each activity must be in some way "standalone" so when it's stopped release any data associate with it. If you need to store some persistant data between activities use sql or some other data storage and if you need some shared resources between activities put them in service. Try to isolate any coupling between activities.

Upvotes: 0

ktingle
ktingle

Reputation: 374

You could use a global counter assuming it is kept in persistent storage. Always keep in mind the system is free to unload and reload activities from device RAM based on pressure from other apps so instance variables of activities are probably not a good choice to house that data.

I think the Android way of handling a scenario like yours would be to manage your connection state in a service and use persistent storage to monitor application state.

Upvotes: 0

Related Questions