25 June, 2014

How to check Android Activity is Currently Running

There are some ways to know whether your application is running mode or not. In this post we will look a bit into checking if your application is the currently active one.

Introduction

So we have a service running which looks for specific behavior on a remote site or something like that. The moment it finds something we want it to present the data to the activity. If the activity is running on the foreground this should not be a problem, however how should we check this? This issue has multiple solutions and all have their pro’s and cons. We will show you the various ways that you can use and list the pro’s and cons.

ActivityManager:

The first thing we will look into is the ActivityManager. The ActivityManager keeps a record of the runnings task and the topmost task. That last one may be interesting for us.

/*** * Checking Whether any Activity of Application is running or not * @param context * @return */ public static boolean isForeground(Context context) {
// Get the Activity Manager
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
// Get a list of running tasks, we are only interested in the last one,
// the top most so we give a 1 as parameter so we only get the topmost.
List< ActivityManager.RunningTaskInfo > task = manager.getRunningTasks(1);
// Get the info we need for comparison.
ComponentName componentInfo = task.get(0).topActivity;
// Check if it matches our package name. if(componentInfo.getPackageName().equals(context.getPackageName())) return true;
// If not then our app is not on the foreground.
return false;
}

Pro: You get the information directly from what your Android knows, more correct may be not possible although Google begs to differ because they strongly suggest to use this only for debugging as it may not be reliable.
Pro: No storing variables of any kind, just look up the task stack of Android. So nothing can be deleted for whatever reason.
Con: Getting the topmost application may not be the entire solution. It can be for some reason that your app is not the topmost app but it should handle it as if it were.
Con: Google’s documentation specifically mentions that we should not use this code for anything but debugging and task managing interfaces so it may not be the best or most reliable option regarding current but also future Android versions.
Con: You need to set a permission in your manifest for android.permission.GET_TASKS. This may be undesirable.
Con: You lack control over this system and you do not know how they handle everything so you have to assume it all goes well, which does not happen in all situations we have heard from our followers.

static variable:

The most simple way (to code) is the use of static variables. Static variables are used quite a bit and there is always debate on the smartness of this but we include it anyway.
public class example extends Activity {
    static boolean isActive = false;
     
    @Override
    protected void onStart() {
        super.onStart();
        isActive = true;
    }
     
    @Override
    protected void onStop() {
        super.onStop();
        isActive = false;
    }
}

Pro: Very easy code
Pro: Hard to be destroyed by user or Android.
Pro: You control for the most part what will be classified as topmost activity due to your own implementation.
Con: Static variables etc. are linked to the class instance, which means that they will only be unloaded if the Classloader that loaded the class is unloaded. This basically means that the static variables is killed when the application is killed altogether. Android however does not destroy an app that often anymore (task history). We should add to this that it often occurs that static variables are not destroyed at all due to complex references to other objects never destroyed and other horrific stuff ;-) Using static variables can result in memory leaks because of this (making an activity or context static for example). Always be sure that you set all the references to null when you do not need them anymore so that the garbage collector can do its thing. This is in our case not a con perse, as we only store 1 boolean and a boolean(value-type) can not create a leak in this example, but we still wanted to be sure that you know whats expected with static variables and why in some information on the internet you encounter discussions on this matter for this problem.
Con: The correct functions are not always called so the state does not always represent the actual state. If an app crashes for example, it will not call the onStop() function. You can remedy this however with creating a default exception handler which can set the variable to false. There may well be other situations we do not have control over that can trigger this kind of situation.
Con: Also static variables are reinitialized to their defaults when they get destroyed. This will give some unreliable behavior. (Crash for example)

Shared Preferences:

Similar to the static variable method, Shared Preferences can be used to share variables with other activities and services from one application.


public class example extends Activity {
     
    @Override
    protected void onStart() {
        super.onStart();
         
        // Store our shared preference
        SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
        Editor ed = sp.edit();
        ed.putBoolean("active", true);
        ed.commit();
    }
     
    @Override
    protected void onStop() {
        super.onStop();
         
        // Store our shared preference
        SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
        Editor ed = sp.edit();
        ed.putBoolean("active", false);
        ed.commit();
         
    }
}

Pro: Shared preferences are not deleted by Android.
Pro: Shared preferences are not reset to a default value.
Pro: You control for the most part what will be classified as topmost activity due to your own implementation.
Con: Shared preferences can be deleted by the user (clear app data) which you do not know of, which can make your system unreliable.
Con: The correct functions are not always called so the state does not always represent the actual state. If an app crashes for example, it will not call the onStop() function. You can remedy this however with creating a default exception handler which can set the shared preferences to the correct values. There may well be other situations we do not have control over that can trigger this kind of situation.

Conclusion:

We prefer to use the shared preferences version. It has the most reliable state information, less application switch/destroy issues, saves us to ask for yet another permission and it gives us more control to decide when our activity is actually the topmost.

2 comments: