Как проверить, является ли действие последним в стеке действий для приложения? - PullRequest
110 голосов
/ 12 мая 2011

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

Ответы [ 10 ]

144 голосов
/ 27 марта 2013

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

Вы можете использовать isTaskRoot () чтобы узнать, является ли действие корнем задачи.

Надеюсь, это поможет

103 голосов
/ 05 июня 2011

ОБНОВЛЕНИЕ (июль 2015 г.):

Поскольку getRunningTasks () устарели, из API 21 лучше следовать raukodraug ответ или Ed Burnette one (я бы предпочел второй).


Есть возможность проверить текущие задачи и их стек, используя ActivityManager .

Итак, чтобы определить, является ли действие последним:

  • запрос разрешений android.permission.GET_TASKS в манифесте.
  • Используйте следующий код:

    ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
    
    List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
    
    if(taskList.get(0).numActivities == 1 &&
       taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
        Log.i(TAG, "This is last activity in the stack");
    }
    

Обратите внимание, что приведенный выше код будет действителен только в том случае, если у вас есть одно задание. Если существует вероятность того, что для вашего приложения будет существовать количество задач - вам нужно будет проверить другие элементы taskList . Узнайте больше о задачах Задачи и Back Stack


15 голосов
/ 28 июля 2015

Существует простейшее решение, вы можете использовать isTaskRoot () в своей деятельности

5 голосов
/ 09 июня 2011

Хотя может быть способ достичь этого (см. Другие ответы), я бы посоветовал вам не делать этого. Обычные приложения для Android не должны знать, собирается ли отображаться главный экран или нет.

Если вы пытаетесь сохранить данные, поместите код сохранения данных в метод onPause (). Если вы пытаетесь дать пользователю возможность изменить свое мнение о существующем приложении, вы можете перехватить клавишу вверх / вниз для клавиши Back и метода onBackPressed () и представить им «Вы уверены?» проворная.

4 голосов
/ 03 июня 2011

Один из способов отследить это - включить маркер при запуске нового действия и проверить, существует ли маркер.

Каждый раз, когда вы начинаете новое занятие, вставьте маркер:

newIntent=new Intent(this, NextOne.class);
newIntent.putExtra(this.getPackageName()+"myself", 0);
startActivity(newIntent);

И вы можете проверить это следующим образом:

boolean islast=!getIntent().hasExtra(this.getPackageName()+"myself")
3 голосов
/ 30 января 2014

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

getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)

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

Intent intent = new Intent(startingActivity, SomeActivityClass.class);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
activity.startActivity(intent);
2 голосов
/ 29 марта 2019

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

решение: я использовал isTaskRoot(), которые возвращают true , если текущая активность является только активностью в вашем стеке , и кроме того, что я также обрабатываю случай, в котором если у меня есть некоторая активность в стеке, переходят к последней активности встек вместо открытия нового пользовательского.

В вашей деятельности

   @Override
    public void onBackPressed() {

        if(isTaskRoot()){
            startActivity(new Intent(currentActivityName.this,ActivityNameYouWantToOpen.class));
            // using finish() is optional, use it if you do not want to keep currentActivity in stack
            finish();
        }else{
            super.onBackPressed();
        }

    }
2 голосов
/ 02 октября 2016

Я создал базовый класс для всех своих действий, расширив AppCompatActivity и имеющий статический счетчик:

public abstract class BasicActivity extends AppCompatActivity {
    private static int activityCounter = 0;

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

    @Override
    public void onDestroy() {
        super.onDestroy();
        --activityCounter;
        if(activityCounter==0) {
            // Last instance code...
        }
    }

    public boolean isLastInstance() { return (activityCounter==1); }
}

До сих пор это работало достаточно хорошо;и независимо от версии API.Конечно, требуется, чтобы все действия расширяли этот базовый класс - что они и делают, в моем случае.

Edit: Я заметил один случай, когда счетчик обнуляется перед приложениемполностью завершается, то есть когда ориентация меняется, и открыта только одна активность.Когда ориентация изменяется, действие закрывается и создается другое, поэтому onDestroyed вызывается для последнего действия, а затем onCreate вызывается, когда создается то же действие с измененной ориентацией.Это поведение должно быть учтено; OrientationEventListener может быть использовано.

0 голосов
/ 09 июня 2011

Единственное, что здесь упущено, - это нажатие кнопки «Домой», когда она активирована, вы не можете обнаружить ее по активности, поэтому было бы лучше программно управлять стеком операций, обрабатывая нажатие кнопки «Назад» и переходя ктребуемое действие или просто выполнение необходимых шагов.

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

0 голосов
/ 03 июня 2011

Android реализует стек Activity, я предлагаю вам прочитать об этом здесь . Похоже, что все, что вы хотите сделать, это получить вызывающую активность: getCallingActivity(). Если текущая активность является первой активностью в вашем приложении, и приложение было запущено с главного экрана, оно должно (я предполагаю) вернуть null.

...