App.xaml.cs ctor вызывается, когда нужно вызвать OnResume()

Если я перемещаюсь в своем приложении и возвращаюсь к Android LaunchScreen с HomeButton, вызывается хук OnSleep(), и это нормально. Если я вернусь в приложение, используя вызов Android TaskManager OnResume(). Если я перемещаюсь в своем приложении с помощью Hardware BackButton, то также вызывается OnSleep(), что нормально, но если я возвращаюсь в свое приложение, вызывается метод OnCreate в MainActivity, который воссоздает приложение.

        global::Xamarin.Forms.Forms.Init (this, bundle);
        DisplayCrashReport();
        LoadApplication (new Gtue.Mobile.App ());

Этого не должно быть. В ctor App.xaml я инициализирую вещи, которые нужно инициализировать только один раз. Я пробовал каждый LaunchMode для MainAcitivity, ничего не помогло.

Есть ли способ узнать, было ли приложение уже инициализировано?


person Alex    schedule 27.11.2017    source источник


Ответы (2)


Ваш класс App расширяется от Xamarin.Forms.Application, а жизненный цикл Xamarin.Forms.Application связан с жизненным циклом Activity. Вы можете найти его в исходный код :

async Task OnStateChanged()
{
    if (_application == null)
        return;

    if (_previousState == AndroidApplicationLifecycleState.OnCreate && _currentState == AndroidApplicationLifecycleState.OnStart)
        _application.SendStart();
    else if (_previousState == AndroidApplicationLifecycleState.OnStop && _currentState == AndroidApplicationLifecycleState.OnRestart)
        _application.SendResume();
    else if (_previousState == AndroidApplicationLifecycleState.OnPause && _currentState == AndroidApplicationLifecycleState.OnStop)
        await _application.SendSleepAsync();
}

Так что вам просто нужно позаботиться о жизненном цикле вашего Activity. Когда вы касаетесь HomeButton, ваше приложение не удаляет MainActivity из стека задач, и MainActivity будет доступно при повторном входе в приложение, поэтому оно не выполнило метод OnCreate.

При касании HomeButton :

[0:] MainActivity OnPause
[0:] MainActivity OnStop
[0:] Forms App OnSleep

При использовании Android TaskManager откройте приложение:

[0:] MainActivity OnRestart
[0:] Forms App OnResume
[0:] MainActivity OnResume

Но когда вы коснетесь аппаратного BackButton, MainActivity будет удалено из стека задачи:

[0:] MainActivity OnPause
[0:] MainActivity OnStop
[0:] Forms App OnSleep
[0:] MainActivity OnDestroy

Когда MainActivity будет уничтожен, ваше приложение будет располагать ресурсом, включая ваш экземпляр Gtue.Mobile.App. И вы могли видеть исходный код метода OnDestroy() :

protected override void OnDestroy()
{
    PopupManager.Unsubscribe(this);
    _platform?.Dispose();

    // call at the end to avoid race conditions with Platform dispose
    base.OnDestroy();
}

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

person Eren Shen    schedule 29.11.2017

Я столкнулся с этой проблемой, когда заметил, что мой конструктор App.xaml.cs вызывается, когда я нажимал кнопку «Домой» на своем устройстве Android, а затем щелкал свое приложение.

Подробный ответ выше подробно описывает правильное «ожидаемое поведение», но для меня это не.

Я получал такой поток при использовании кнопки «Домой» или кнопки «Назад» -

**On Debug Start**
MainActivity:OnCreate
XF:AppCtor
XF:OnStart
MainActivity:OnResume

**Press Home Button**
MainActivity:OnPause
XF:OnSleep

**Launch App via Click on App Icon**
MainActivity:OnCreate
XF:AppCtor

Поиски в конце концов привели меня к -

Приложение перезапускается, а не возобновляется

Что, в свою очередь, привело к следующему коду Xamarin в верхней части MainActivity OnCreate:

        if (!IsTaskRoot)
        {
            string action = Intent.Action;
            if (Intent.HasCategory(Android.Content.Intent.CategoryLauncher) &&
                !string.IsNullOrEmpty(Intent.Action) &&
                action == Android.Content.Intent.ActionMain)
            {
                Finish();
                return;
            }
        }

Что, кажется, решает первоначальную перезагрузку, по крайней мере.

Я также объединил это с -

 LaunchMode = LaunchMode.SingleTask

Чтобы остановить некоторые махинации с двойной активностью при нажатии на уведомление на экране уведомлений.

person WickedW    schedule 22.11.2019