web-dev-qa-db-fra.com

Android: comment vérifier si l'activité est en cours?

Existe-t-il un moyen simple de déterminer si une activité donnée est active ou non? 

if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else
121
user560571

Vous pouvez utiliser une variable static au sein de l'activité.

class MyActivity extends Activity {
     static boolean active = false;

      @Override
      public void onStart() {
         super.onStart();
         active = true;
      } 

      @Override
      public void onStop() {
         super.onStop();
         active = false;
      }
}

Le seul inconvénient est que si vous l'utilisez dans deux activités qui se lient l'une à l'autre, onStop sur la première est parfois appelé après onStart en seconde. Donc, les deux pourraient être vrais brièvement.

Selon ce que vous essayez de faire (mettre à jour l'activité en cours depuis un service?). Vous pouvez simplement enregistrer un écouteur statique dans le service dans votre méthode activity onStart. Le bon écouteur sera disponible lorsque votre service voudra mettre à jour l'interface utilisateur.

193
siliconeagle

Je pense plus clair comme ça:

  public boolean isRunning(Context ctx) {
        ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

        for (RunningTaskInfo task : tasks) {
            if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName())) 
                return true;                                  
        }

        return false;
    }
36
Xenione

Bien mieux que d'utiliser une variable statique et de suivre OOP

Shared Preferences peut être utilisé pour partager des variables avec d’autres activities et services d’un 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();

    }
}

Utilisez les préférences partagées. Il contient les informations d’État les plus fiables, moins de problèmes de commutation/destruction d’application, nous évite de demander une autre autorisation et nous donne plus de contrôle pour décider quand notre activité est réellement la plus importante. voir détails ici abd ici aussi

24
Xar E Ahmer

J'ai utilisé la méthode MyActivity.class et getCanonicalName et j'ai obtenu une réponse.

protected Boolean isActivityRunning(Class activityClass)
{
        ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

        for (ActivityManager.RunningTaskInfo task : tasks) {
            if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName()))
                return true;
        }

        return false;
}
20
mahyar

Une option sans utiliser aucune variable auxiliaire est:

activity.getWindow().getDecorView().getRootView().isShown()

où activité est f.e .: this ou getActivity ().

La valeur renvoyée par cette expression change dans onStart ()/onStop (), qui sont les événements qui déclenchent/arrêtent la présentation de l'activité sur le téléphone.

18
GaRRaPeTa

C'est un code permettant de vérifier si un service particulier est en cours d'exécution. Je suis à peu près sûr que cela peut également fonctionner pour une activité tant que vous modifiez getRunningServices avec getRunningAppProcesses () ou getRunningTasks (). Jetez un oeil ici http://developer.Android.com/reference/Android/app/ActivityManager.html#getRunningAppProcesses ()

Modifiez Constants.PACKAGE et Constants.BACKGROUND_SERVICE_CLASS en conséquence.

    public static boolean isServiceRunning(Context context) {

    Log.i(TAG, "Checking if service is running");

    ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);

    List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

    boolean isServiceFound = false;

    for (int i = 0; i < services.size(); i++) {

        if (Constants.PACKAGE.equals(services.get(i).service.getPackageName())){

            if (Constants.BACKGROUND_SERVICE_CLASS.equals(services.get(i).service.getClassName())){
                isServiceFound = true;
            }
        }
    }

    Log.i(TAG, "Service was" + (isServiceFound ? "" : " not") + " running");

    return isServiceFound;

}
9
kkudi

merci kkudi! J'ai pu adapter votre réponse pour travailler pour une activité ... voici ce qui a fonctionné dans mon application ..

public boolean isServiceRunning() { 

ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE); 
    List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE); 
    isServiceFound = false; 
    for (int i = 0; i < services.size(); i++) { 
        if (services.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.lyo.AutoMessage/com.lyo.AutoMessage.TextLogList}")) {
            isServiceFound = true;
        }
    } 
    return isServiceFound; 
} 

cet exemple vous donnera un vrai ou un faux si topActivity correspond à ce que l'utilisateur fait. Donc, si l’activité pour laquelle vous recherchez n’est pas affichée (c’est-à-dire onPause), vous n’obtiendrez aucune correspondance. Pour ce faire, vous devez également ajouter l'autorisation à votre manifeste.

<uses-permission  Android:name="Android.permission.GET_TASKS"/>

J'espère que cela a été utile!

6
alyon2002

Je pense que la réponse acceptée est un moyen terrible de gérer cela.

Je ne sais pas quel est le cas d'utilisation, mais considérez une méthode protégée dans la classe de base.

@protected
void doSomething() {
}

et le remplacer dans la classe dérivée. 

Lorsque l'événement se produit, appelez simplement cette méthode dans la classe de base. La classe «active» correcte le gérera alors. La classe elle-même peut alors vérifier si ce n'est pas Paused().

Mieux encore, utilisez un bus d’événement tel que de GreenRobot , de Square , mais celui-ci est obsolète et suggère d’utiliser RxJava

4
Boy

Je me rends compte que ce problème est assez ancien, mais je pense que cela vaut toujours la peine de partager ma solution car elle pourrait être utile à d’autres.

Cette solution n'était pas disponible avant la sortie des composants d'architecture Android.

L'activité est au moins partiellement visible

getLifecycle().getCurrentState().isAtLeast(STARTED)

L'activité est au premier plan

getLifecycle().getCurrentState().isAtLeast(RESUMED)
3
malinjir

Il existe un moyen beaucoup plus simple que tout ce qui précède et cette approche ne nécessite pas l’utilisation de Android.permission.GET_TASKS dans le manifeste, ni que la question des conditions de concurrence ou des fuites de mémoire soit signalée dans la réponse acceptée.

  1. Créez une variable STATIC dans l'activité principale. Statique permet à d'autres activités de recevoir les données d'une autre activité. onPause() définir cette variable false , onResume et onCreate() définir cette variable true .

    private static boolean mainActivityIsOpen;
    
  2. Affectez des getters et des setters de cette variable.

    public static boolean mainActivityIsOpen() {
        return mainActivityIsOpen;
    }
    
    public static void mainActivityIsOpen(boolean mainActivityIsOpen) {
        DayView.mainActivityIsOpen = mainActivityIsOpen;
    }
    
  3. Et puis d'une autre activité ou service

    if (MainActivity.mainActivityIsOpen() == false)
    {
                    //do something
    }
    else if(MainActivity.mainActivityIsOpen() == true)
    {//or just else. . . ( or else if, does't matter)
            //do something
    }
    
3
coolcool1994

qu'en est-il de activity.isFinishing()

2
Ambareesh B

ActivityLifecycleCallbacks est un excellent moyen de garder une trace de toutes les activités dans App:

public class BaseActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {

private ActivityState homeState, contentState;

@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
    if (activity instanceof HomeActivityv2) {
        homeState = ActivityState.CREATED;
    } else if (activity instanceof ContentDisplayActivity) {
        contentState = ActivityState.CREATED;
    }
}

@Override
public void onActivityStarted(Activity activity) {
    if (activity instanceof HomeActivityv2) {
        homeState = ActivityState.STARTED;
    } else if (activity instanceof ContentDisplayActivity) {
        contentState = ActivityState.STARTED;
    }
}

@Override
public void onActivityResumed(Activity activity) {
    if (activity instanceof HomeActivityv2) {
        homeState = ActivityState.RESUMED;
    } else if (activity instanceof ContentDisplayActivity) {
        contentState = ActivityState.RESUMED;
    }
}

@Override
public void onActivityPaused(Activity activity) {
    if (activity instanceof HomeActivityv2) {
        homeState = ActivityState.PAUSED;
    } else if (activity instanceof ContentDisplayActivity) {
        contentState = ActivityState.PAUSED;
    }
}

@Override
public void onActivityStopped(Activity activity) {
    if (activity instanceof HomeActivityv2) {
        homeState = ActivityState.STOPPED;
    } else if (activity instanceof ContentDisplayActivity) {
        contentState = ActivityState.STOPPED;
    }
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}

@Override
public void onActivityDestroyed(Activity activity) {
    if (activity instanceof HomeActivityv2) {
        homeState = ActivityState.DESTROYED;
    } else if (activity instanceof ContentDisplayActivity) {
        contentState = ActivityState.DESTROYED;
    }
}

public ActivityState getHomeState() {
    return homeState;
}

public ActivityState getContentState() {
    return contentState;
}
}

ActivityState:

public enum ActivityState {
    CREATED, STARTED, RESUMED, PAUSED, STOPPED, DESTROYED;
}

Étendez la classe d’application et fournissez sa référence dans le fichier Manifest Android:

import Android.app.Application;

public final class BaseApplication extends Application {
private BaseActivityLifecycleCallbacks baseALC;

@Override
public void onCreate() {
    super.onCreate();
    baseALC = new BaseActivityLifecycleCallbacks();
    this.registerActivityLifecycleCallbacks(baseALC);

}

public BaseActivityLifecycleCallbacks getBaseALC() {
    return baseALC;
}
}

Cliquez n'importe où sur Activité pour connaître le statut d'une autre activité:

private void checkAndLaunchHomeScreen() {
    Application application = getApplication();
    if (application instanceof BaseApplication) {
        BaseApplication baseApplication = (BaseApplication) application;
        if (baseApplication.getBaseALC().getHomeState() == null || baseApplication.getBaseALC().getHomeState() == ActivityState.DESTROYED) {
            //Do anything you want
        }
    }
}

https://developer.Android.com/reference/Android/app/Application.ActivityLifecycleCallbacks.html

2
Suyash Gupta

En plus de la réponse acceptée , si vous avez plusieurs instances de l'activité, vous pouvez utiliser un compteur à la place:

class MyActivity extends Activity {

     static int activeInstances = 0;

     static boolean isActive() {
        return (activeInstance > 0)
     }

      @Override
      public void onStart() {
         super.onStart();
         activeInstances++;
      } 

      @Override
      public void onStop() {
         super.onStop();
         activeInstances--;
      }
}
1
james_alvarez

J'ai utilisé un chèque if (!a.isFinishing()) et il semble faire ce dont j'ai besoin. a est l'instance d'activité. Est-ce incorrect? Pourquoi personne n'a essayé cela?

1
lxknvlk

Utilisez une diffusion ordonnée. Voir http://Android-developers.blogspot.nl/2011/01/processing-ordered-broadcasts.html

Dans votre activité, enregistrez un destinataire dans onStart, annulez l’inscription dans onStop. Désormais, lorsqu'un service doit par exemple gérer quelque chose que l'activité peut éventuellement améliorer, envoyez une diffusion ordonnée à partir du service (avec un gestionnaire par défaut dans le service lui-même). Vous pouvez maintenant répondre à l'activité lorsqu'elle est en cours d'exécution. Le service peut vérifier les données de résultat pour voir si la diffusion a été gérée et, le cas échéant, prendre les mesures appropriées.

1
nickmartens1980
if(!activity.isFinishing() && !activity.isDestroyed())
1
Codelicious

As-tu essayé.. 

    if (getActivity() instanceof NameOfYourActivity){
        //Do something
    }
1
E.Mathew

Pas sûr que ce soit une "bonne" façon de "faire les choses".
S'il n'y a pas de moyen API de résoudre la (ou une) question que vous ne le pensiez un peu, peut-être que vous faites quelque chose de mal et que vous lisez plus de documents à la place, etc.
(D'après ce que j'ai compris, les variables statiques sont une méthode généralement erronée dans Android. Cela pourrait fonctionner, mais il y aura certainement des cas où cela ne fonctionnera pas [par exemple, en production, sur des millions d'appareils]).
Exactement dans votre cas, je suggère de penser pourquoi avez-vous besoin de savoir si une autre activité est vivante? .. vous pouvez démarrer une autre activité pour obtenir un résultat afin d’obtenir sa fonctionnalité. Vous pouvez également dériver la classe pour obtenir ses fonctionnalités, etc.
Meilleures salutations.

1
user2399321

Si vous êtes intéressé par l'état de cycle de vie de l'instance spécifique de l'activité, la solution de siliconeagle semble correcte, sauf que la nouvelle variable "active" doit être une variable d'instance, plutôt que statique.

1
Jonathan Taylor

Trouver une solution de contournement facile avec le code suivant

@Override 
protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) { 
                // Activity is being brought to front and not being  created again, 
                // Thus finishing this activity will bring the last viewed activity to foreground
                finish(); 
            } 
    }
0
Varun Bhatia

Utilisez la variable isActivity pour vérifier si l’activité est active ou non.

private boolean activityState = true;

 @Override
protected void onDestroy() {
    super.onDestroy();
    activityState = false;
}

Puis vérifier 

if(activityState){
//add your code
}
0
Faran Tariq