Подтвердить что ты не робот

OnRestart против OnResume - вопрос о жизненном цикле Android

Моя конечная цель - иметь приложение, которое запускает блок кода, когда он (приложение, а не активность) открывается после его оставления (обратно с главного экрана и т.д.)

В соответствии с жизненным циклом активности это должно быть событие onRestart() для каждой активности (по крайней мере, как я его интерпретирую)

Оба типа onRestart() и onResume() вызываются, возвращаются ли я к активности в приложении (кнопка "Назад" ), и когда приложение вызывается обратно.

Учитывая эту диаграмму enter image description here

Я интерпретирую это следующим образом:

  • RED= перемещение между действиями в приложении
  • BLUE= переход к активности вне приложения

Непонятно ли мое понимание?

EDIT (Уточнение конкретного варианта использования)

Я пытаюсь использовать onRestart() для репликации некоторой логики безопасности (проверка PIN-кода), найденной в onCreate(), но она вызывается, даже когда я нажимаю кнопку "Назад" внутри приложения...

4b9b3361

Ответ 1

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

Если я понимаю, что вы хотите сделать правильно, вы хотите поместить свой код в onCreate, а не в onRestart.

СМОТРИТЕ КОМНАТУЮ РЕЗЬБУ ДЛЯ ОТВЕТА

Ответ 2

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

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

Ответ 3

Вот как это сделать: -

  • У вас есть базовая активность, из которой производятся все ваши действия.

  • Добавьте к базовому действию: -

    int nAppState;
    
    protected override void OnCreate(Bundle bundle)
    {
            base.OnCreate(bundle);
            nAppState = 0;
            .
            .
    }
    protected override void OnStop()
    {
            AppState();
            base.OnStop();
    }
    public static int IMPORTANCE_BACKGROUND = 400;
    
    protected override void AppState()
    {
            ActivityManager am = (ActivityManager)GetSystemService(Context.ActivityService);
            IList<ActivityManager.RunningAppProcessInfo> list2 = am.RunningAppProcesses;
            foreach (ActivityManager.RunningAppProcessInfo ti in list2)
            {
                    if (ti.ProcessName.ToLower() == "com.mycompany.myapp")
                    {
                            nAppState = ti.Importance;
                            break;
                    }
            }
    }
    protected override void OnRestart()
    {
            base.OnRestart();
            if (nAppState == IMPORTANCE_BACKGROUND)
            {
                    // Show a log in screen
                    RunOnUiThread(delegate { StartActivity(new Intent(this, typeof(LoginAppearActivity))); });
                    nAppState = 0;
            }
    }
    
  • Обратите внимание, что это в Mono С#, это будет тот же код для Java, я оставлю его для вас, чтобы преобразовать его.

Ответ 4

Да, ваши утверждения для красного и синего правильны.

Однако обратите внимание на альтернативный путь от onPause() и onStop(). Процесс, убиваемый по соображениям памяти, является a) из вашего контроля и b) незаметен для вас, если вы только используете onRestart() для обнаружения "возврата" к активности.

Ответ 5

У вас есть возможность избежать предыдущего действия, избегая/удаляя активность, входящую в стек, путем установки некоторого флага перед вызовом функции startActivity (intent):

intent.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY);

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