繁体   English   中英

WP7 从 Tombstone 恢复并返回页面

[英]WP7 recover from Tombstone and return to page

从墓碑中恢复时,是否有一种很好/优雅的方式可以返回用户所在的页面? 我不确定我的应用程序还是它的工作方式,但我总是回到我的主页。

我的应用程序设置有一个主页,该主页具有 Pivot 控件和几个 Pivot 项目将导航到新页面。 如果有意义的话,我的 Naigation 看起来像这样:

PivotItem1 -> PageA
PivotItem2 -> PageB -> PageC
PivotItem3 -> PageD -> PageE - PageF(按 PageF 上的返回按钮将使用非线性导航服务返回主页面)

因此,如果用户在任何页面上建立墓碑,我想将它们返回到该页面并让 BackStack 可用,这样导航就不会被搞砸。

我正在使用 MVVM Light 和非线性导航服务,如果这有助于或损害我想要完成的工作。

@Tyler,Cyberherbalist:我很遗憾我不能就在你的讨论中“添加评论”。 我的声誉或其他任何东西都太低了。 我也没有任何博客可以在那里发布并给你一个链接。 我就写在这里,因为我认为它值得关注和写在某个地方,所以其他人也可能会从中检查/使用/permormanceprofit。

..所以,请原谅我的这篇“离题文章”:)

虽然我不知道如何很好地解决问题 - 我的解决方案通常是手动收集导航历史堆栈,将其放入 iso,并在激活时恢复并跳转到正确/最后一个位置 - 我可以告诉你一点关于墓碑的一点。

问题是,如果您的应用程序已停用,这并不意味着它已被删除。 停用只是意味着您的应用程序被换出屏幕。 在 Mango 版本中,您可以点击并按住“返回”设备按钮,查看当前打开了哪些应用程序,然后跳转到任何应用程序。 “激活”是您的应用程序被唤醒的时间。 即使在 WP7 SDK+Emulator 的早期版本中,我也在从我的应用程序中调用外部媒体播放器,而我的应用程序几乎从未被物理杀死。 停用/激活总是在我的应用程序“停止”的地方恢复我的应用程序。 所有内存中的对象都未触及。

当设备资源不足时会发生墓碑,并且必须“杀死”一些后台任务以释放 memory。 我相信当设备的屏幕保护程序下拉并且设备长时间处于待机状态时也会发生这种情况。 Tombstoning 将真正杀死您的应用程序,所有内存中的对象都将被销毁/删除等等。 唯一能幸存下来的是 AppSettings 和 ISO 商店。 当您的应用程序处于停用的 state 时,才会保证发生墓碑。

那么,您可以看到哪些生命周期?

1)“冻结/待机/散焦”:

  • 发射
  • ... (在职的)
  • 停用(移至后台)
  • ...(保留在 memory 中,可能进程/线程被冻结,但我怀疑)
  • (...)
  • 已激活(移至前台,不发生导航)
  • ... (在职的)
  • 结束

2)“墓碑”:

  • 发射
  • ... (在职的)
  • 停用(移至后台)
  • ...(保留在 memory 中,可能进程/线程被冻结,但我怀疑)
  • ...(墓碑,从 memory 中删除,一切都被摧毁)
  • (...)
  • ...(清洁应用 object 构建)
  • 已激活(移至前台)
  • 导航(我认为,总是到清单中设置的第一个默认页面,但我现在不确定)
  • (在职的)
  • 结束

这意味着,墓碑化可能有点难以检测,但也意味着您总是有时间尝试在 deactivated-eventhandler 中与您的 state 相同。

这也意味着,(除非有一些我还不知道的通知服务),检测来自墓碑的简历是否依赖...的唯一方法是依赖最致命/不愉快的效果其中:清除您的 memory。

想象一个最简单的情况:您的应用程序 object 有一个属性“private bool _tomb_test”。 它可以是任何类型的任何属性/字段。 你也可以使用你的“object ViewModel{get;set}”。

首先要记住的是,不要在构造函数中设置它,也不要分配内联默认值。 让它漂浮。 只要 App object 是全新创建的,编译器/运行时就会将其设置为默认值。 这就是重点!

现在:

  • 在已启动(不是 ctor,!!)中,设置“_tomb_test = true”
  • 在停用状态下,将您的最小持久性 state 保存到 ISO
  • 在激活中,检查:
    • 如果 _tomb_test==false 这意味着,你被墓碑。 你的 memory 是干净的,所有物体都被破坏了。 根据上次写入 ISO 的数据恢复您的 state,然后启动所有作业以重新填充/重新下载/重新加载/重新计算/等应用程序的所有其他部分 state
    • 但是,如果_tomb_test==true,这意味着墓碑没有发生。 您的 memory 未受影响。 也许只是 GC 介入并收集了死者。 所有活着的物体都还活着。 该应用程序可以免费运行,就好像什么都没发生过一样。

虽然它看起来很漂亮,但请原谅我这个冗长的免责声明:

我在当前的应用程序中成功使用它并 100% 成功,但我不能说这是保证平台的行为。 我还没有时间在 MSDN 上挖掘事实。 以上所有内容均来自我对 7.0 和 7.1 SDK 版本的观察。

上述方法的小问题是它依赖于(未经证实的?)假设,即 memory 清除以全有或全无的方式工作。

也就是说,假设所有对象都被清除,或者没有发生清除(当前事实:应用程序 object 并观察到从头开始重新创建,甚至发生初始导航以重新创建 UI。在其他情况下,两者都没有发生)。

对于错误的假设......我无法想象谁以及为什么会决定在 .net 世界中实施部分 memory 清除。 完全清除意味着终止应用程序。 部分清除意味着破坏 GC 代中的随机活对象,并让所有 rest 保持活动状态,并带有悬垂的句柄或无效的句柄。 我无法想象。 我没有观察到。 因此,我认为这是全有或全无。

顺便提一句。 如果您观察到部分清除并找到一种主要确定的方法来导致它,因此其他人也可能看到它,请大声广播::)

我有一个类似的重导航应用程序,它可以满足您的需求(也使用非线性导航服务)。 在我的情况下,我将用户的当前页面/数据透视项目存储在隔离存储中,以及指示应用程序是否从墓碑返回的令牌(或布尔值)。 当用户导航到一个页面时,页面加载设置iso中的当前页面值,如果页面有pivot,它也会将当前pivot设置为第一个。 pivot_changed 事件具有将新的当前 pivot 更改为用户刚刚更改的代码的代码。

当应用程序处于墓碑过程中时,会触发 app_deactivate 事件,并且在这里我将 iso 中的 IsTombstoned 值设置为 true。

当用户从墓碑返回时,主 page_load 首先检查应用程序是否正在从墓碑重新激活 (IsTombstoned=true),如果是,它会立即导航到名称存储在 iso 中的页面。 当当前的 page_load 触发时,它会检查 IsTombstoned=true,如果是,则将其设置为 false(恢复正常),如果页面上有 pivot,则将选定的 pivot 项设置为存储的当前 ZDCA758FD47F2E975ZBBF。 如果页面没有 pivot 控件,则当前 pivot 将留空。 如果在被墓碑化时页面中有动态内容,您还需要为其提供恢复。

抱歉,我没有向您展示代码,但我远离工作站,我无法使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM