应用程序启动时,App.xaml.cs中的函数被调用两次

时间:2014-09-16 17:57:59

标签: c# windows-phone-8 app.xaml

我正在构建一个Windows手机应用程序,我遇到了这个问题:我在FirstRun()文件中有一个App.xaml.cs函数,用于检查应用程序是否第一次运行。我有两个消息框,每次都给我看(第一次运行而不是第一次运行)。问题是,当我第一次运行应用程序时,我收到消息“第一次运行”但在此之后,没有继续,我得到另一条消息“不首先运行”,程序没有进入需要的功能在第一次运行时执行。什么可以导致IsFirstRun()函数的这个“双重”调用,并返回不同的结果?以下是功能:

 public static bool IsFirstRun()
    {
        if (!settings.Contains(FIRST_RUN_FLAG)) //First time running
        {
            settings.Add(FIRST_RUN_FLAG, false);
            return true;
        }
        return false;   
    }

UriMapper帮我找到了正确的页面:

公共类FirstRunUriMapper:UriMapperBase     {         公开覆盖Uri MapUri(Uri uri)         {

        if (uri.OriginalString == "/LaunchPage.xaml")
        {
            MessageBox.Show("Searching for LaunchPage...");
            if (App.IsFirstRun())
            {
                MessageBox.Show("First run...Should show introductionPage...");
                uri = new Uri("/MainPage.xaml", UriKind.Relative);
            }
            else
            {
                MessageBox.Show("...Should show MainPage...");
                uri = new Uri("/IntroductionPage.xaml", UriKind.Relative);
            }
        }
        return uri;
    }
}

修改 如我所知,我为整个班级提供了现在正常工作的修改后的UriMapper,但仍无法找到导致双MapUri()方法调用的原因:

  public class FirstRunUriMapper : UriMapperBase
{

    public override Uri MapUri(Uri uri)
    {

        if (uri.OriginalString == "/LaunchPage.xaml")
        {
            if (App.FirstRun)
            {
                if (App.IsFirstRun())
                {
                    uri = new Uri("/IntroductionPage.xaml", UriKind.Relative);
                }
                else
                {
                    uri = new Uri("/IntroductionPage.xaml", UriKind.Relative);
                    App.FirstRun = false;
                }
            }
            else
            {
                uri = new Uri("/MainPage.xaml", UriKind.Relative);
            }
        }
        return uri;
    }
}

App.xaml.cs类:

公共部分类App:应用程序     {

    private static string FIRST_RUN_FLAG = "FIRST_RUN_FLAG";
    private static IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
    public static bool FirstRun = true;

    /// <summary>
    /// Provides easy access to the root frame of the Phone Application.
    /// </summary>
    /// <returns>The root frame of the Phone Application.</returns>
    public static PhoneApplicationFrame RootFrame { get; private set; }

    /// <summary>
    /// Checks if the app runs for the first time
    /// </summary>
    /// <returns>True if the app runs for the first time, otherwise false.</returns>
    public static bool IsFirstRun()
    {
        if (!settings.Contains(FIRST_RUN_FLAG)) //First time running
        {
            settings.Add(FIRST_RUN_FLAG, false);
            return true;
        }
        return false;   
    }


    public void loadModel()
    {
        string dataFromAppSettings;
        ContactLensesModel model;

        //Search for the string into the Application Settings
        if (IsolatedStorageSettings.ApplicationSettings.TryGetValue(MainPage.Model.modelKey, out dataFromAppSettings))
        {
            model = JsonConvert.DeserializeObject<ContactLensesModel>(dataFromAppSettings);
            MainPage.Model = model;
        }
        else //The model does not exist
        {
            MainPage.Model = null;

        }
    }

    public void saveModel()
    {
        //Convert to a JSON format
        var modelData = JsonConvert.SerializeObject(MainPage.Model);

        //Save the model to the settings
        IsolatedStorageSettings.ApplicationSettings[MainPage.Model.modelKey] = modelData;
        IsolatedStorageSettings.ApplicationSettings.Save();
    }


    /// <summary>
    /// Constructor for the Application object.
    /// </summary>
    public App()
    {
        // Global handler for uncaught exceptions.
        UnhandledException += Application_UnhandledException;

        // Standard XAML initialization
        InitializeComponent();

        // Phone-specific initialization
        InitializePhoneApplication();

        // Language display initialization
        InitializeLanguage();

        // Show graphics profiling information while debugging.
        if (Debugger.IsAttached)
        {
            // Display the current frame rate counters.
            Application.Current.Host.Settings.EnableFrameRateCounter = true;

            // Show the areas of the app that are being redrawn in each frame.
            //Application.Current.Host.Settings.EnableRedrawRegions = true;

            // Enable non-production analysis visualization mode,
            // which shows areas of a page that are handed off to GPU with a colored overlay.
            //Application.Current.Host.Settings.EnableCacheVisualization = true;

            // Prevent the screen from turning off while under the debugger by disabling
            // the application's idle detection.
            // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
            // and consume battery power when the user is not using the phone.
            PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
        }

    }

    // Code to execute when the application is launching (eg, from Start)
    // This code will not execute when the application is reactivated
    private void Application_Launching(object sender, LaunchingEventArgs e)
    {
        RootFrame.UriMapper = new FirstRunUriMapper();
        loadModel();
    }



    // Code to execute when the application is activated (brought to foreground)
    // This code will not execute when the application is first launched
    private void Application_Activated(object sender, ActivatedEventArgs e)
    {
        loadModel();
        if (e.IsApplicationInstancePreserved == false)
        {
            RootFrame.UriMapper = new FirstRunUriMapper();

        }
    }

    // Code to execute when the application is deactivated (sent to background)
    // This code will not execute when the application is closing
    private void Application_Deactivated(object sender, DeactivatedEventArgs e)
    {
        saveModel();
    }



    // Code to execute when the application is closing (eg, user hit Back)
    // This code will not execute when the application is deactivated
    private void Application_Closing(object sender, ClosingEventArgs e)
    {
        saveModel();
    }

    // Code to execute if a navigation fails
    private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
    {
        if (Debugger.IsAttached)
        {
            // A navigation has failed; break into the debugger
            Debugger.Break();
        }
    }

    // Code to execute on Unhandled Exceptions
    private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
    {
        if (Debugger.IsAttached)
        {
            // An unhandled exception has occurred; break into the debugger
            Debugger.Break();
        }
    }

    #region Phone application initialization

    // Avoid double-initialization
    private bool phoneApplicationInitialized = false;

    // Do not add any additional code to this method
    private void InitializePhoneApplication()
    {
        if (phoneApplicationInitialized)
            return;

        // Create the frame but don't set it as RootVisual yet; this allows the splash
        // screen to remain active until the application is ready to render.
        RootFrame = new PhoneApplicationFrame();
        RootFrame.Navigated += CompleteInitializePhoneApplication;

        // Handle navigation failures
        RootFrame.NavigationFailed += RootFrame_NavigationFailed;

        // Handle reset requests for clearing the backstack
        RootFrame.Navigated += CheckForResetNavigation;

        // Ensure we don't initialize again
        phoneApplicationInitialized = true;
    }

    // Do not add any additional code to this method
    private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
    {
        // Set the root visual to allow the application to render
        if (RootVisual != RootFrame)
            RootVisual = RootFrame;

        // Remove this handler since it is no longer needed
        RootFrame.Navigated -= CompleteInitializePhoneApplication;
    }

    private void CheckForResetNavigation(object sender, NavigationEventArgs e)
    {
        // If the app has received a 'reset' navigation, then we need to check
        // on the next navigation to see if the page stack should be reset
        if (e.NavigationMode == NavigationMode.Reset)
            RootFrame.Navigated += ClearBackStackAfterReset;
    }

    private void ClearBackStackAfterReset(object sender, NavigationEventArgs e)
    {
        // Unregister the event so it doesn't get called again
        RootFrame.Navigated -= ClearBackStackAfterReset;

        // Only clear the stack for 'new' (forward) and 'refresh' navigations
        if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh)
            return;

        // For UI consistency, clear the entire page stack
        while (RootFrame.RemoveBackEntry() != null)
        {
            ; // do nothing
        }
    }

    #endregion

    // Initialize the app's font and flow direction as defined in its localized resource strings.
    //
    // To ensure that the font of your application is aligned with its supported languages and that the
    // FlowDirection for each of those languages follows its traditional direction, ResourceLanguage
    // and ResourceFlowDirection should be initialized in each resx file to match these values with that
    // file's culture. For example:
    //
    // AppResources.es-ES.resx
    //    ResourceLanguage's value should be "es-ES"
    //    ResourceFlowDirection's value should be "LeftToRight"
    //
    // AppResources.ar-SA.resx
    //     ResourceLanguage's value should be "ar-SA"
    //     ResourceFlowDirection's value should be "RightToLeft"
    //
    // For more info on localizing Windows Phone apps see http://go.microsoft.com/fwlink/?LinkId=262072.
    //
    private void InitializeLanguage()
    {
        try
        {
            // Set the font to match the display language defined by the
            // ResourceLanguage resource string for each supported language.
            //
            // Fall back to the font of the neutral language if the Display
            // language of the phone is not supported.
            //
            // If a compiler error is hit then ResourceLanguage is missing from
            // the resource file.
            RootFrame.Language = XmlLanguage.GetLanguage(AppResources.ResourceLanguage);

            // Set the FlowDirection of all elements under the root frame based
            // on the ResourceFlowDirection resource string for each
            // supported language.
            //
            // If a compiler error is hit then ResourceFlowDirection is missing from
            // the resource file.
            FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection);
            RootFrame.FlowDirection = flow;
        }
        catch
        {
            // If an exception is caught here it is most likely due to either
            // ResourceLangauge not being correctly set to a supported language
            // code or ResourceFlowDirection is set to a value other than LeftToRight
            // or RightToLeft.

            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }

            throw;
        }
    }


}

}

2 个答案:

答案 0 :(得分:0)

static bool first = true;

public override Uri MapUri(Uri uri)
{

    if (uri.OriginalString == "/LaunchPage.xaml")
    {
        if (first) MessageBox.Show("Searching for LaunchPage...");

        if (App.IsFirstRun())
        {
            if (first) MessageBox.Show("First run...Should show introductionPage...");
            uri = new Uri("/MainPage.xaml", UriKind.Relative);
        }
        else
        {
            if (first) MessageBox.Show("...Should show MainPage...");
            uri = new Uri("/IntroductionPage.xaml", UriKind.Relative);
        }
        }

        first = false;
    }
    return uri;
}

答案 1 :(得分:0)

查看this SO question

上的示例

您是否尝试过连接RootFrame.UriMapper而不是覆盖?

private void Application_Launching(object sender, LaunchingEventArgs e)
{
     RootFrame.UriMapper = new YourUriMapper();
}