WP8:快速应用程序恢复+辅助磁贴+ MainPage = 2个实例

时间:2014-02-05 18:24:46

标签: c# windows-phone-8 windows-phone secondary-live-tile

我遇到了同样的问题:

http://social.msdn.microsoft.com/Forums/wpapps/en-us/af8615e7-8e90-4069-aa4d-3c4a84a6a3d0/windows-phone-8-fast-app-resume-with-deeplinks?forum=wpdevelop

我不是C#或WP专家,所以请耐心等待。

  • 我有辅助磁贴链接到“/MainPage.xaml?id=XX”。
  • 我启用了快速应用恢复功能。 (ActivationPolicy =应用清单中的“恢复”)
  • 我的应用中只有一个页面:MainPage.xaml。

问题:当我使用辅助磁贴(“/MainPage.xaml?id=XX”)恢复应用时,我会看到前一个实例的简要视图(已经恢复)和然后MainPage再次初始化,创建一个新实例。实际上,该应用程序在向我展示之前打开的内容后从头开始加载。

这显然是不受欢迎的行为。我想使用现有实例来执行我​​的任务。


尝试1 : 使用e.Cancel = true;取消导航到MainPage.xaml:
(使用官方Fast App Resume sample中的App.xaml.cs代码来确定应用的启动方式)

...
else if (e.NavigationMode == NavigationMode.New && wasRelaunched)
{
  // This block will run if the previous navigation was a relaunch
  wasRelaunched = false;

  if (e.Uri.ToString().Contains("="))
  {
    // This block will run if the launch Uri contains "=" (ex: "id=XX") which
    // was specified when the secondary tile was created in MainPage.xaml.cs
    sessionType = SessionType.DeepLink;

    e.Cancel = true; // <======================== Here

    // The app was relaunched via a Deep Link.
    // The page stack will be cleared.
  }
}
...

问题 :这样做,我的OnNavigatedTo事件处理程序永远不会触发,因此我的查询字符串永远不会被解析。

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
  String navId;
  if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
  {
    if (NavigationContext.QueryString.TryGetValue("id", out navId))
    {
      MessageBox.Show(navId.ToString()); // Not reached
    }
  }
  ...

尝试2 : 使用e.Cancel = true;取消导航到MainPage.xaml, AND 将Uri传递给MainPage中的方法:

// App.xaml.cs
...
else if (e.NavigationMode == NavigationMode.New && wasRelaunched)
{
  // This block will run if the previous navigation was a relaunch
  wasRelaunched = false;

  if (e.Uri.ToString().Contains("="))
  {
    // This block will run if the launch Uri contains "=" (ex: "id=XX") which
    // was specified when the secondary tile was created in MainPage.xaml.cs
    sessionType = SessionType.DeepLink;

    e.Cancel = true;

    MainPage.GoToDeepLink(e.Uri); // <======================== Here

    // The app was relaunched via a Deep Link.
    // The page stack will be cleared.
  }
}
...

// MainPage.xaml.cs
public static void GoToDeepLink(Uri uri) // <======================== Here
{
  // Convert the uri into a list and navigate to it.
  string path = uri.ToString();
  string id = path.Substring(path.LastIndexOf('=') + 1);

  MyList list = App.ViewModel.ListFromId(Convert.ToInt32(id));
  pivotLists.SelectedItem = list;
}

问题 :我收到错误, pivotLists 是非静态的,因此需要对象引用。我认为为了使这个工作,我需要创建一个新的MainPage实例(MainPage newMainPage = new MainPage();)并调用newMainPage.pivotLists.SelectedItem = list; - 但我不知道如何使用newMainPage而不是现有的/替换它......或者如果那是我想要/不会引起进一步的问题/并发症。


我不知道解决这个问题的方法是什么,我可能会走向完全错误的方向。如果可以,请使用代码示例简单地保留所有建议,我仍在学习。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

似乎当您从辅助磁贴重新打开应用程序时,它会被重新激活并创建新的MainPage实例(即使之前的运行中有一个)。如果我理解正确的话,我就设法做了这样的事情:

在app.xaml.cs中:

我添加了一个变量,指示在从辅助磁贴导航后是否应该返回到上一个MainPage - 它需要是静态的,因为我想从MainPage访问它

public static bool returnPage = false;

在RootFrame_Navigating中我将此变量设置为true:

// ...
else if (e.NavigationMode == NavigationMode.New && wasRelaunched)
{
   // This block will run if the previous navigation was a relaunch
   wasRelaunched = false;
   returnPage = true;
// ...

在ClearBackStackAfterReset中 - 在返回时阻止删除旧页面:

// ...
if (e.NavigationMode != NavigationMode.New || returnPage)
      return;
// ...

在MainPage.cs中:

我已经改变了一个小构造函数,因为我不希望看到一个新的页面闪烁:

public MainPage()
{
  if (!App.returnPage)
     InitializeComponent();
}

在MainPage中我也是从辅助磁贴传递的变量 - 它也是静态的,因为我只需要它的一个实例:

private static string navId = "";

诀窍的核心 - OnNavigatedTo:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
  if (App.returnPage)
  {
     App.returnPage = false;
     NavigationContext.QueryString.TryGetValue("id", out navId);
     NavigationService.GoBack();
  }
  else if (e.NavigationMode != NavigationMode.Reset)
  {
     // normal navigation
  }
}

它的工作原理如下:

  • 当您正常启动App时,returnPage为false,一切正常
  • 当您从辅助磁贴激活它时,很少发生这种情况:

    1。首先使用NavigationMode.Reset导航到您的上一页 - 我们对它不感兴趣,所以我关闭它 - 什么都不应该发生 2.然后程序尝试创建MainPage的新实例,但returnPage为true,并且由于if语句,InitializeComponent将不会运行。就在此之后,在OnNavigatedTo中,程序保存传递的查询字符串并导航回以前的MainPage实例 - 从上次运行开始 3.最后我们使用NavigationMode.Back导航到正确的MainPage,我们将查询字符串保存在静态变量中。

你必须意识到两件事:首先 - 可能它可能很少重建(我不确定是否需要重新启动等等) - 你需要调试它并看看你可以摆脱什么。第二 - 您可能需要使用Tombstone案例测试您的应用程序。

希望这有帮助。