Android: как проверить, запущена ли работа?

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

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

Ответ 1

В операции можно использовать переменную 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;
      }
}

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

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

Ответ 2

Мне кажется более понятным:

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

Ответ 3

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

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

где действует fe: this или getActivity().

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

Ответ 4

Я использовал метод MyActivity.class и 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;
}

Ответ 5

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

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 здесь также

Ответ 6

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

Измените Constants.PACKAGE и Constants.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;

}

Ответ 7

спасибо 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"/>

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

Ответ 8

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

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

@protected
void doSomething() {
}

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

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

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

Ответ 9

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

Это решение не было доступно до выпуска компонентов архитектуры Android.

Активность хотя бы частично видна

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

Деятельность на переднем плане

getLifecycle().getCurrentState().isAtLeast(RESUMED)

Ответ 10

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

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

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

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

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

Ответ 11

if(!activity.isFinishing() && !activity.isDestroyed())

Из официальных документов:

Занятие isFinishing()

Проверьте, находится ли это действие в процессе завершения, потому что вы вызвали на нем метод finish() или кто-то еще запросил его завершение. Это часто используется в onPause(), чтобы определить, просто ли действие приостанавливается или полностью завершается.

Занятие isDestroyed()

Возвращает true, если последний вызов onDestroy() был сделан для Activity, поэтому этот экземпляр теперь мертв.

Ответ 12

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

Ответ 13

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

Расширьте класс Application и предоставьте его ссылку в файле Android Manifest:

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

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

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

Ответ 14

как насчет activity.isFinishing()

Ответ 15

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

Ответ 16

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

Ответ 17

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

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

Ответ 18

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

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

Ответ 19

Ты пытался..

    if (getActivity() instanceof NameOfYourActivity){
        //Do something
    }

Ответ 20

Обнаружено легкое обходное решение со следующим кодом

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

Ответ 21

Используйте переменную isActivity, чтобы проверить, активна ли активность или нет.

private boolean activityState = true;

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

Тогда проверь

if(activityState){
//add your code
}

Ответ 22

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

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

Это работает для меня одновременно с несколькими действиями.