Android: Как проверить, работает ли activity?

есть ли простой способ определить, активна ли определенная активность? Я хочу делать определенные вещи, в зависимости от активности действующих. например:

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

18 ответов


можно использовать static переменная в пределах действия.

class MyActivity extends Activity {
     static boolean active = false;

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

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

единственный gotcha заключается в том, что если вы используете его в двух действиях, которые связаны друг с другом, то onStop на первом иногда называется после onStart в секунду. Так как может быть верно, коротко.

в зависимости от того, что вы пытаетесь сделать (обновить текущей деятельности из сервиса?). Вы можете просто зарегистрировать статический прослушиватель в службе в своей деятельности onStart метод, то верный слушатель будет доступна, когда ваша служба хочет обновить UI.


Я думаю, более ясно, что:

  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;
    }

гораздо лучший способ, чем использовать статическую переменную и следовать ООП

Shared Preferences может использоваться для обмена переменными с другими activities и услуги от одного 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();

    }
}

использовать общие предпочтения. Он имеет самую надежную информацию о состоянии, меньше проблем с переключением/уничтожением приложений, экономит нас, чтобы попросить еще одно разрешение, и дает нам больше контроля, чтобы решить, когда наша деятельность на самом деле является самой верхней. см.подробности здесь abd здесь


опция без использования какой-либо вспомогательной переменной:

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

где активность f.e.: это или getActivity ().

значение, возвращаемое этим выражением, изменяется в onStart () / onStop (), которые являются событиями, которые запускают / останавливают отображение макета действия на телефоне.


Я MyActivity.класс и метод getCanonicalName, и я получил ответ.

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;
}

Это код для проверки того, запущена ли конкретная служба. Я уверен, что он может работать и для действия, пока вы меняете getRunningServices с помощью getRunningAppProcesses() или getRunningTasks(). Посмотрите здесь http://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses()

Постоянные Изменения.Пакет и константы.BACKGROUND_SERVICE_CLASS соответственно

    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;

}

спасибо kkudi! Я смог адаптировать ваш ответ к работе для деятельности... вот что сработало в моем приложении..

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; 
} 

этот пример даст вам true или false, если topActivity соответствует тому, что делает пользователь. Поэтому, если активность, которую вы проверяете, не отображается (т. е. onPause), вы не получите совпадения. Кроме того, для этого необходимо добавить разрешение в манифест..

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

Я надеюсь, это было полезно!


Я думаю, что принятый ответ-Это ужасный способ справиться с этим.

Я не знаю, что такое вариант использования, но, пожалуйста, рассмотрите защищенный метод в базовом классе

@protected
void doSomething() {
}

и переопределить его в производном классе.

когда событие происходит, просто вызовите этот метод в базовом классе. Правильный "активный" класс будет обрабатывать его. Затем сам класс может проверить, не является ли он Paused().

еще лучше, используйте шину событий, как GreenRobot-х, площади, но это устарело и предлагает использовать RxJava


есть гораздо более простой способ, чем все, что выше, и этот подход не требует использования android.permission.GET_TASKS в манифесте, или имеют вопрос условий гонки или утечек памяти, указанных в принятом ответе.

  1. сделайте статическую переменную в основной деятельности. Static позволяет другим действиям получать данные от другого действия. onPause() установить эту переменную false, onResume и onCreate() установить эту переменную правда.

    private static boolean mainActivityIsOpen;
    
  2. назначить геттеры и сеттеры этой переменной.

    public static boolean mainActivityIsOpen() {
        return mainActivityIsOpen;
    }
    
    public static void mainActivityIsOpen(boolean mainActivityIsOpen) {
        DayView.mainActivityIsOpen = mainActivityIsOpen;
    }
    
  3. а затем от другой деятельности или службы

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

насчет activity.isFinishing()


Не уверен, что это "правильный" способ "делать вещи".
Если нет способа API решить (или a) вопрос, чем вы должны немного подумать, возможно, вы делаете что-то неправильно и читаете больше документов и т. д.
(Как я понял, статические переменные обычно неверны в android. Конечно, это может сработать, но обязательно будут случаи, когда это не сработает[например, в производстве, на миллионах устройств]).
Именно в вашем случае я предлагаю подумать Почему вы нужно знать, жива ли другая активность?.. вы можете запустить другое действие для результата, чтобы получить его функциональность. Или вы можете наследовать класс, чтобы получить его функциональность и так далее.
с уважением.


Если вас интересует состояние жизненного цикла конкретного экземпляра activity, решение siliconeagle выглядит правильным, за исключением того, что новая "активная" переменная должна быть переменной экземпляра, а не статической.


используйте упорядоченную трансляцию. Смотри http://android-developers.blogspot.nl/2011/01/processing-ordered-broadcasts.html

в вашей деятельности зарегистрируйте приемник в onStart, отмените регистрацию в onStop. Теперь, когда, например, службе необходимо обработать что-то, что действие может сделать лучше, отправьте заказанную трансляцию из службы (с обработчиком по умолчанию в самой службе). Теперь вы можете отвечать в действии, когда оно выполняется. Служба может проверить результат данных, чтобы увидеть, если трансляция была обработана, и если не принять соответствующие меры.


я использовал проверки if (!a.isFinishing()) и, кажется, делает то, что мне нужно. a экземпляр активности. Это неправильно? Почему никто не попробовал?


кроме принято отвечать, Если у вас есть несколько экземпляров действия, вы можете использовать счетчик вместо:

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--;
      }
}

ActivityLifecycleCallbacks-отличный способ отслеживать все действия в приложении:

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.DESTR0YED;
    } else if (activity instanceof ContentDisplayActivity) {
        contentState = ActivityState.DESTR0YED;
    }
}

public ActivityState getHomeState() {
    return homeState;
}

public ActivityState getContentState() {
    return contentState;
}
}

ActivityState:

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

расширьте класс приложения и укажите его ссылку в файле манифеста 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;
}
}

Ckeck в любом месте от активности для статуса другой деятельности:

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

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


найдено простое обходное решение со следующим кодом

@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(); 
            } 
    }

эта работа, если у вас нет такой же активности на переднем плане. Если вы открываете из уведомления не работает, я внес некоторые коррективы и пришел с этим:

public static boolean ativo = false;
public static int counter = 0;

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

@Override
protected void onStart() {
    super.onStart();
    ativo = true;
}

@Override
protected void onStop() {
    super.onStop();
    if (counter==1) ativo = false;
}

@Override
protected void onDestroy() {
    counter--;
    super.onDestroy();
}

это работает для меня с несколькими активностями, открытыми одновременно.