SuspensionManager в универсальных приложениях Windows ничего не делает для быстрого переключения приложений.

У меня возникли проблемы с пониманием того, как я могу выполнить код при быстром переключении приложений (т. е. нажать кнопку Windows/Пуск, чтобы отобразить начальный экран в эмуляторе телефона, а затем нажать кнопку «Назад», чтобы вернуться в приложение).

Чтобы упростить проблему, я запустил новое универсальное приложение Windows, в котором в качестве базового кода используется шаблон «Приложение Visual C# Hub (универсальные приложения)» (поскольку он включает в себя SuspensionManager и NavigationHelper). Поскольку сам Hub меня не интересует, я удалил все содержимое Grid из HubPage.xaml и просто добавил TextBox с именем TimeTextBox:

...
    <Grid x:Name="LayoutRoot">
        <TextBox Name="TimeTextBox"/>
    </Grid>
</Page>

Затем в HubPage.xaml.cs я добавил следующую простую строку в метод NavigationHelper_LoadState:

private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
    var sampleDataGroups = await SampleDataSource.GetGroupsAsync();
    this.DefaultViewModel["Groups"] = sampleDataGroups;

    TimeTextBox.Text = DateTime.Now.TimeOfDay.ToString();
}

Если я выполню приложение на эмуляторе телефона после применения этих простых изменений, приложение будет показывать время дня при загрузке страницы, например: 16:08:53.4390827.

Я хочу, чтобы это время обновлялось каждый раз, когда я перехожу на эту страницу. Но если я использую события жизненного цикла из Visual Studio для имитации приостановки, когда я отправляю событие Resume, время остается тем же: 16:08:53.4390827, и точка останова в этой строке подтвердит, что метод NavigationHelper_LoadState не получает выполняется при возобновлении.

Это объясняется тем, что App.xaml.cs в том виде, в каком он есть в шаблоне, не предоставляет никакого прослушивателя для события Resume, поэтому ничего не выполняется. Добавление следующих нескольких строк исправляет это:

    public App()
    {
        this.InitializeComponent();
        this.Suspending += this.OnSuspending;

        this.Resuming += App_Resuming;
    }

    async void App_Resuming(object sender, object e)
    {
        await SuspensionManager.RestoreAsync();
    }

Поэтому, если я снова запускаю приложение на эмуляторе телефона, теперь я получаю фактическое время после возобновления работы. Здорово! Проблема в том, что эти события приостановки/возобновления не запускаются, когда я просто нажимаю кнопку Windows на телефоне, а затем нажимаю кнопку «Назад».

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

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

Спасибо!


person irodrisa    schedule 14.08.2014    source источник
comment
Я только что понял, что проблема была вызвана запуском приложения через Visual Studio. По какой-то причине присоединение Visual Studio к эмулятору мешает событиям Suspend/Resume. После развертывания, если я запускаю приложение непосредственно из эмулятора, все работает, и метод NavigationHelper_LoadState действительно выполняется без проблем.   -  person irodrisa    schedule 15.08.2014
comment
Что ж, добро пожаловать в SO в любом случае. ;)   -  person Chris W.    schedule 15.08.2014


Ответы (1)


Здесь нет ничего плохого. Это поведение по умолчанию. При отладке приложения Windows Phone 8.1 из Visual Studio единственный способ инициировать событие Suspend/Resume — использовать события жизненного цикла в VS. Но когда вы запускаете приложение без VS, эти методы сработают, как и ожидалось. :)

person Heshan    schedule 19.10.2014