Как проверить, если активность все еще в стеке?

Какой лучший способ проверить, находится ли активность в стеке, чтобы перезвонить?

Intent i = new Intent(getApplicationContext(),MyClass.class);
startActivity(i);

3 ответа

Решение

Посмотрите на API ActivityManager

Чтобы получить экземпляр ActivityManager, используйте этот код:

ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );

Я удивлен, насколько непопулярен этот (вид) вопрос (ы).

Позвольте мне начать с решения в первую очередь:
поскольку ActivityManager.getRunningTasks устарела начиная с API 21,
Мы должны найти другой способ узнать, какие действия находятся в спине. И я понял, что мы действительно можем реализовать наш собственный "стек"!

Я объявил ArrayList в MyOwnApplication:

private ArrayList<Class> runningActivities = new ArrayList<>();

И добавил открытые методы для доступа и изменения этого списка:

public void addThisActivityToRunningActivityies (Class cls) {
    if (!runningActivities.contains(cls)) runningActivities.add(cls);
}

public void removeThisActivityFromRunningActivities (Class cls) {
    if (runningActivities.contains(cls)) runningActivities.remove(cls);
}

public boolean isActivityInBackStack (Class cls) {
    return runningActivities.contains(cls);
}

В BaseActivity где все виды деятельности расширяют его:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((MyOwnApplication)getApplication()).addThisActivityToRunningActivityies(this.getClass());
    }

@Override
protected void onDestroy() {
    super.onDestroy();
    ((MyOwnApplication)getApplication()).removeThisActivityFromRunningActivities(this.getClass());
}

И тогда вы можете легко использовать isActivityInBackStack Проверять.

ПОЧЕМУ ЭТО НЕОБХОДИМО?

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

Предположим, у меня есть приложение, в котором есть навигационная панель почти во всех действиях.
Я перемещаюсь из MainActivity в ActivityA, а затем создал ChildActivityB от ActivityA, Обратите внимание, что ActivityA не является родителем ChildActivityB поскольку ChildActivityB может быть открыт из других действий, таких как уведомление.

Обратите внимание, что, ChildActivityB также есть ящик. Я могу перейти к ActivityA через ящик, вместо нажатия кнопки вверх или назад. Теперь представьте, что вы проходите через такой процесс: Действие A -> ChildActivity B -> Drawer -> Действие A -> ChildActivityB -> Drawer -> Действие A..... В backstack будут созданы бесконечные действия.
Чтобы исправить такое поведение, нам нужно использовать Intent Flags:

(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);

Все идет нормально. Тем не менее, у меня есть пользовательские анимации перехода активности с помощью overridePendingTransition(), Я заметил, что если я поставлю вышеупомянутые флаги намерения вместе с overridePendingTransition(), в анимации будет сбой, потому что активность уничтожается в середине анимации из-за флага Intent.FLAG_ACTIVITY_CLEAR_TOP,

Теперь, если я смогу определить, ActivityA в backstack или нет, поведение будет идеальным:

private void navigateToDrawerItems(Class cls) {
    drawerLayout.closeDrawer(GravityCompat.END);
    Intent intent = new Intent(this, cls);
    if (((MyOwnApplication)getApplication()).isActivityInBackStack(cls)) {
        intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    } else {
        startActivity(intent);
        overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
    }
}

Вы можете переключать глобальную переменную как индикатор внутри onCreate() а также onDestory() определенного класса, ИЛИ внутри onActivityCreated() а также onActivityDestroyed() ActivityLifecycleCallbacks.

например:

  registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {

      @Override
      public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
          if (activity instanceof YourActivity) {
              myGlobalData.setActExist(true);
          } 
      }

      @Override
      public void onActivityDestroyed(Activity activity) {
          if (activity instanceof YourActivity) {
              myGlobalData.setActExist(false);
          }
      }
  });
Другие вопросы по тегам