Reputation: 1648
I would like to ask You about best way to determine that my app is currently visible to user (foreground). I know there are two solutions:
ActivityManager
but this is very expensive way. boolean
variable and change its state in onResume()
and onPause()
of every Activity
. This solution has one main
disadvantage additional code to remember about.Do you know any other, better way? What do you think, whats better and why?
EDIT
According to my second sollution skywell suggest that we can create an Activity
where in onResume()
and onPause()
we can change state of our boolean
variable. Every Activity
in application should extends our new Activity
. But this idea generate few new problems:
Activity
for every kind (For example ActionBarActivity
) of needed Activity.Great explanation of my second solution is provide in DroidAks's post.
Upvotes: 0
Views: 93
Reputation: 655
Answer made by DroidAks is good, but not good enough. As we all know, having state in static
variables isn't the prettiest thing to do. Doing that means that You have to remember that You need to manage this state and clean it up. Also, in this case, having static
variables in Application
class means that Your classes will be solely reliant on this particular Application
class. What if You'd like to make a library out of Your code, which would be used in many apps?
Here is my proposal:
public class MyApplication extends Application
{
private boolean visible;
public boolean isVisible()
{
return visible;
}
//use Application events to manage app visibility state
}
While in Your Activity
code:
public class MyActivity extends Activity
{
@Override
protected void onResume()
{
super.onResume();
MyApplication myApp = (MyApplication)this.getApplication();
//myApp.isVisible();
}
}
If the above MyApplication
class implementation was not enough (there may be trouble with setting visible
to false
), then move on to even more proper solution of this problem:
public /*abstract*/ class MyActivity extends Activity
{
private boolean visible;
protected boolean isVisible()
{
return visible;
}
//use Activity events to manage activity visibility state
//for ex.
@Override
protected void onResume()
{
super.onResume();
visible = true;
}
}
public class MyConcreteActivity extends MyActivity
{
@Override
protected void onResume()
{
super.onResume(); // calls onResume from base MyActivity,
// thus always setting visible state properly
//isVisible();
}
}
Remember to update Your manifest file accordingly.
EDIT
We have to duplicate that new Activity for every kind (For example ActionBarActivity) of needed Activity. We still have to remember about extends correct Activity, it can be problematic in larger teams.
All of above is solved by having an interface, that is passed around to classes requiring functionality of asking the object about its visibility state.
public interface Hideable
{
boolean isVisible();
}
If one would like to use Your class, then this class should explicitly have Hideable
interface as one of its constructor/public method parameters. If You would like to restrict the parameter to extend Activity
AND implement Hideable
then this generic example (with wildcard usage) is right thing to do:
//TODO design new parameter name
public <T extends Activity & Hideable> void myMethod(T iNeedToBeHideableActivity)
After seeing such a method, the developer should:
activities
already implementing this
interface. activity
.The requirement of proper behavior is obvious in this case - the interface should announce, whether particular object is visible or not.
PS. This is not a very ugly duplication, as each implementation could be different in some ways. For example, Application
class lacks onDestroy
event, so implementation of Hideable
interface should be different there.
EDIT
Improved above suggestion by adding generics.
Upvotes: 0
Reputation: 327
If you want to track whether the app is in foreground or not. This might be the best way. Check for the states of your app by yourself using Activity.onPause, Activity.onResume methods. Store "visibility" status in some other class. Now implementat your own Application class as:
public class MyApplication extends Application
{
public static boolean isActivityVisible()
{
return activityVisible;
}
public static void activityResumed()
{
activityVisible = true;
}
public static void activityPaused()
{
activityVisible = false;
}
private static boolean activityVisible;
}
Now add onResume()
and onPause()
in every activity
We can use AndroidLifecycleCallbacks to track whether the app is currently visible to user or not. AndroidLifecycleCallbacks were added in API level 14. Hope it helps you.
@Override
protected void onResume() {
super.onResume();
MyApplication.activityResumed();
}
@Override
protected void onPause() {
super.onPause();
MyApplication.activityPaused();
}
Also add in your manifest following code.
<application
android:name="your.app.package.MyApplication"
android:icon="@drawable/icon"
android:label="@string/app_name" >
Upvotes: 1