快速应用程序恢复不起作用

Posted

技术标签:

【中文标题】快速应用程序恢复不起作用【英文标题】:Fast App Resume not working 【发布时间】:2014-12-19 14:14:57 【问题描述】:

我正在尝试为 Windows Phone 8 实现快速应用恢复。我关注了the link at MSDN。

这是 XAML 中的代码:

<Tasks>
  <DefaultTask Name="_default" NavigationPage="MainPage.xaml" ActivationPolicy="Resume"/>
</Tasks>

这是 app.xaml.cs 中的代码

    public static PhoneApplicationFrame RootFrame  get; private set; 
    bool wasRelaunched = false;      
    bool mustClearPagestack = false;      
    IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

    enum SessionType
    
        None,
        Home,
        DeepLink
    

    private SessionType sessionType = SessionType.None;

    public App()
               
        UnhandledException += Application_UnhandledException;         
        InitializeComponent();           
        InitializePhoneApplication();        
        InitializeLanguage();       
        if (Debugger.IsAttached)
                       
            Application.Current.Host.Settings.EnableFrameRateCounter =true;  
           PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
        
    

    private void Application_Launching(object sender, LaunchingEventArgs e)
    
        RemoveCurrentDeactivationSettings();
    

    private void Application_Activated(object sender, ActivatedEventArgs e)
    

        mustClearPagestack = CheckDeactivationTimeStamp();

        if (!e.IsApplicationInstancePreserved)
        
            RestoreSessionType();
        
    

     private void Application_Deactivated(object sender, DeactivatedEventArgs e)
     
        SaveCurrentDeactivationSettings();
    

    private void Application_Closing(object sender, ClosingEventArgs e)
    
        RemoveCurrentDeactivationSettings();
    

    private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
    
        if (Debugger.IsAttached)
        

            Debugger.Break();
        
    

    private void Application_UnhandledException(object sender,ApplicationUnhandledExceptionEventArgs e)
    
        if (Debugger.IsAttached)
        

            Debugger.Break();
        
    

    private bool phoneApplicationInitialized = false;

    private void InitializePhoneApplication()
    
        if (phoneApplicationInitialized)
            return;


        RootFrame= new PhoneApplicationFrame();

        RootFrame.Background = new SolidColorBrush(Color.FromArgb(255, 27, 200, 174));
        RootFrame.Navigated += CompleteInitializePhoneApplication;


        RootFrame.NavigationFailed += RootFrame_NavigationFailed;


        RootFrame.Navigated += CheckForResetNavigation;
        RootFrame.Navigating += RootFrame_Navigating;


        phoneApplicationInitialized = true;
    

    void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
    
        if (e.Uri.ToString().Contains(@"/MainPage.xaml") == true && !AppPrefManager.Instance.IsFastAppResumeEnabled)
        
            RootFrame.Dispatcher.BeginInvoke(delegate
            
                if (!AppPrefManager.Instance.IsVirginLaunchCompleted)
                
                    RootFrame.Navigate(new Uri(Constants.kIntroPage, UriKind.Relative));
                
                else
                
                    RootFrame.Navigate(new Uri(Constants.kMainPage, UriKind.Relative));
                
            );
            e.Cancel = true;
        


        if (sessionType == SessionType.None && e.NavigationMode == NavigationMode.New)
        

            if (e.Uri.ToString().Contains("DeepLink=true"))
            
                sessionType = SessionType.DeepLink;
            
            else if (e.Uri.ToString().Contains("/MainPage.xaml"))
            
                sessionType = SessionType.Home;
            
        


        if (e.NavigationMode == NavigationMode.Reset)
        

            wasRelaunched = true;
        
        else if (e.NavigationMode == NavigationMode.New && wasRelaunched)
        

            wasRelaunched = false;

            if (e.Uri.ToString().Contains("DeepLink=true"))
            


                sessionType = SessionType.DeepLink;

            
            else if (e.Uri.ToString().Contains("/MainPage.xaml"))
            

                if (sessionType == SessionType.DeepLink)
                

                    sessionType = SessionType.Home;
                
                else
                
                    if (!mustClearPagestack)
                    

                        e.Cancel = true;
                        RootFrame.Navigated -= ClearBackStackAfterReset;
                    
                
            

            mustClearPagestack = false;
        
    

    private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
    

        if (RootVisual != RootFrame)
            RootVisual = RootFrame;

        RootFrame.Navigated -= CompleteInitializePhoneApplication;
    

    private void CheckForResetNavigation(object sender, NavigationEventArgs e)
    

        if (e.NavigationMode == NavigationMode.Reset)
            RootFrame.Navigated += ClearBackStackAfterReset;
    

    private void ClearBackStackAfterReset(object sender, NavigationEventArgs e)
    

        RootFrame.Navigated -= ClearBackStackAfterReset;


        if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh)
            return;


        while (RootFrame.RemoveBackEntry() != null)
        
            ; 
        
    

     private void InitializeLanguage()
    
        try
        
            FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection);
            RootFrame.FlowDirection = flow;
        
        catch
        
            if (Debugger.IsAttached)
            
                Debugger.Break();
            

            throw;
        
    

    bool CheckDeactivationTimeStamp()
    
        DateTimeOffset lastDeactivated;

        if (settings.Contains("DeactivateTime"))
        
            lastDeactivated = (DateTimeOffset)settings["DeactivateTime"];
        

        var currentDuration = DateTimeOffset.Now.Subtract(lastDeactivated);

        return TimeSpan.FromSeconds(currentDuration.TotalSeconds) > TimeSpan.FromSeconds(30);
    

    public bool AddOrUpdateValue(string Key, Object value)
    
        bool valueChanged = false;


        if (settings.Contains(Key))
        

            if (settings[Key] != value)
            

                settings[Key] = value;
                valueChanged = true;
            
        

        else
        
            settings.Add(Key, value);
            valueChanged = true;
        
        return valueChanged;
    

    public void RemoveValue(string Key)
    

        if (settings.Contains(Key))
        
            settings.Remove(Key);
        
    

    public void SaveCurrentDeactivationSettings()
    
        if (AddOrUpdateValue("DeactivateTime", DateTimeOffset.Now))
        
            settings.Save();
        

        if (AddOrUpdateValue("SessionType", sessionType))
        
            settings.Save();
        

    

    public void RemoveCurrentDeactivationSettings()
    
        RemoveValue("DeactivateTime");
        RemoveValue("SessionType");
        settings.Save();
    

    void RestoreSessionType()
    
        if (settings.Contains("SessionType"))
        
            sessionType = (SessionType)settings["SessionType"];
        
    

假设当我在 ThirdPage 中时。我按下 Windows 按钮。然后我从开始屏幕按我的应用程序图标。而不是从 ThirdPage 恢复的应用程序。它首先显示 ThirdPage,然后从 MainPage 开始。

【问题讨论】:

【参考方案1】:

默认情况下,当应用程序通过应用程序磁贴启动时,应用程序仍会导航到默认页面。 如果您愿意,可以在 RootFrame_Navigated 方法中检查会话类型并取消该导航。

默认模板在 app.xaml.cs 中添加了一个 CheckNavigation 方法,该方法在使用 NavigationMode Reset 进行导航后清除后台堆栈。

您可以在此处检查您的应用是否应该停留在最后一页,或者是否最好重置并重新开始。

可在此处找到处理不同激活类型的示例: MSDN Fast Resume Sample, App.xaml.cs

(方法:RootFrame_Navigated)

【讨论】:

我使用的是相同的代码。我正面临这个问题。 在 RootFrame_Navigating 中,您是否更改了 /MainPage.xaml 的测试以匹配您的主页名称?您是否更改了应用程序其他地方的所有导航以添加“DeepLink=true”参数?需要这些步骤才能让示例代码为您工作。这样做后它对我来说工作正常。【参考方案2】:

列出的代码会搞砸。它与 cmets 不匹配。 查看 RootFrame_Navigating - 底部的 mustClearPagesStack 设置为 false - 但查看原始 MSDN 链接中的 cmets - 上面的两个地方说必须清除页面堆栈....但是因为标志设置为 false 它搞砸了向上。因此,在顶部设置标志为假,然后在它所说的两个“如果条件”中将其设置为真。 然后它将像冠军一样工作。

【讨论】:

以上是关于快速应用程序恢复不起作用的主要内容,如果未能解决你的问题,请参考以下文章

没有情节提要的 UIViewController 状态恢复不起作用

Compact-Framework:最小化和恢复不起作用

快速转场不起作用?

为啥恐慌恢复以局部变量返回值不起作用?

快速无效计时器不起作用

快速护照会话不起作用