0
votes

Im creating an app with many webservice calls and in order to make the flow better and perhaps pass the windows store requirements regarding the startup time,I have decided to use extended splash screen to load all the main data and then share this data accross the different pages using global variables that i have defined in App.xaml.cs.

My question is: is it correct to use global variables this way, and is there any risk that this data will be lost when the app gets suspended/resumed?, because i am only initialising this data from he extended splash screen that.

Below is my code

here is some code from the app.xaml.cs page: here i define global variables, load background image for the app from my webservice before i go to the extende splash screen

   sealed partial class App : Application
        {

            **public string[] NavigateData { get; set; }
            public NavigationCacheMode NavigationCacheMode { get; set; }**



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

                //Cache the page     
                this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
            }


            protected async override void OnLaunched(LaunchActivatedEventArgs args)
            {
                Frame rootFrame = Window.Current.Content as Frame;
               //---------------------------------Live tile
                var uris = new List<Uri> 
                { 
                    new Uri("http://XXX.XX.XX.XXX/WebApi/WebService.asmx/GetFirstTile"),

                    new Uri("http://XXX.XX.XX.XXX/WebApi/WebService.asmx/GetSecondTile"),
                    new Uri("http://XXX.XX.XX.XXX/WebApi/WebService.asmx/GetStatisticTile"),
                    new Uri("http://XXX.XX.XX.XXX/WebApi/WebService.asmx/GetNewsTile1"),
                    new Uri("http://XXX.XX.XX.XXX/WebApi/WebService.asmx/GetNewsTile2"),

                };

                TileUpdater LiveTileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();         
                LiveTileUpdater.EnableNotificationQueue(true);  // Enable notifications
                LiveTileUpdater.Clear();  // Clear the current set of updates
                LiveTileUpdater.StartPeriodicUpdateBatch(uris, PeriodicUpdateRecurrence.HalfHour);
                //------------------------------Live tile section end


                // Do not repeat app initialization when the Window already has content,
                // just ensure that the window is active
                if (rootFrame == null)
                {
                    // Create a Frame to act as the navigation context and navigate to the first page
                    rootFrame = new Frame();
                    weather.Common.SuspensionManager.RegisterFrame(rootFrame, "appFrame");


       //When the app is loaded first time it calls the web service to get wich background picture to use
             //--------------------------Getting and setting background image for all the pages--------------------
                    string appBackgGround;
       ServiceReference.WebServiceSoapClient webServiceObj = new ServiceReference.WebServiceSoapClient();
                    // Get the name of the Background picture
       appBackgGround = await webServiceObj.GetBackgroundImageAsync();


                    // Her we set the application background Image for all pages  "backgroundImageBlueSky.jpg"
                    rootFrame.Background = new ImageBrush
                    {
                        Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill,
                        ImageSource = new BitmapImage { UriSource = new Uri("ms-appx:///Assets/"+appBackgGround) }

                    };
      //--------------------------Bacground image end--------------------



                    if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
                    {
                        //TODO: Load state from previously suspended application
                        await weather.Common.SuspensionManager.RestoreAsync();
                    }

                    // Place the frame in the current Window
                    Window.Current.Content = rootFrame;
                }

                if (rootFrame.Content == null)
                {
                    // When the navigation stack isn't restored navigate to the first page,
                    // configuring the new page by passing required information as a navigation
                    // parameter
                    //Go to the extended splash screen
                    if (!rootFrame.Navigate(typeof(ExtendedSplashScreen), rootFrame.GetNavigationState()))
                    {
                        throw new Exception("Failed to create initial page");
                    }


                }
                // Ensure the current window is active
                //create the about page
                var _Helper = new Flyouts.SettingsHelper();
                _Helper.AddCommand<Flyouts.About>("About");
                Window.Current.Activate();
            }


            private async void OnSuspending(object sender, SuspendingEventArgs e)
            {
                var deferral = e.SuspendingOperation.GetDeferral();
                //TODO: Save application state and stop any background activity
                await weather.Common.SuspensionManager.SaveAsync();
                deferral.Complete();
            }


        }
    }   

ExtendedSplashScreen: Here i load some initialisation data for the app from a webservice before i go to the Mainpage. The data is saved to the global variable defined in App.xaml.cs. While this data is loading a progress ring is displayed. After the data is loaded i move on to the mainpage

public sealed partial class ExtendedSplashScreen : Page
{

    parameterItem max1DayAgo = new parameterItem();
    parameterItem min1DayAgo = new parameterItem();


    public ExtendedSplashScreen()
    {
        this.InitializeComponent();
    }

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {

        string[] periodSelector     = { "1DayAgo", "1WeekAgo", "1MonthAgo" };
        string[] modeSelector       = { "max", "min" };
        string[] parameterSelector  = { "umtTemp1", "umtWindSpeed", "umtAdjBaromPress", "umtRainRate" };

        //---------------GETTING WEBSERVICE DATA FOR STARTUP-------------
        //Create a webservice object
        ServiceReference.WebServiceSoapClient webServiceObj = new ServiceReference.WebServiceSoapClient();       
        var getMax1DayAgoObj = await webServiceObj.GetSelectedMaxMinDataAsync(parameterSelector, periodSelector[0], modeSelector[0]);

        //create an object that holds min data for yesterday

        var getMin1DayAgoObj = await webServiceObj.GetSelectedMaxMinDataAsync(parameterSelector, periodSelector[0], modeSelector[1]);
        //Save arrayOfValue and arrayOfUnit to a parameterItem object. these objects are created during startup
        // and the can be accessed and updated by all methods in this page later we will see that maxMinButton_Click method
        //for the maxMinButton will use these data
        max1DayAgo.arrayOfValue = getMax1DayAgoObj.arrayOfValue;
        max1DayAgo.arrayOfUnit = getMax1DayAgoObj.arrayOfUnit;

        min1DayAgo.arrayOfValue = getMin1DayAgoObj.arrayOfValue;
        min1DayAgo.arrayOfUnit = getMin1DayAgoObj.arrayOfUnit;

        string[] startupData = new string[13];

        startupData[0] = " " + max1DayAgo.arrayOfValue[0] + " " + max1DayAgo.arrayOfUnit[0]; //    maxTemp 
        startupData[1] = " " + max1DayAgo.arrayOfValue[1] + " " + max1DayAgo.arrayOfUnit[1]; //    maxWindSped 
        startupData[2] = " " + max1DayAgo.arrayOfValue[2] + " " + max1DayAgo.arrayOfUnit[2]; //    maxAirPressure 
        startupData[3] = " " + max1DayAgo.arrayOfValue[3] + " " + max1DayAgo.arrayOfUnit[3];//     maxRainfall

        startupData[4] = " " + min1DayAgo.arrayOfValue[0] + " " + min1DayAgo.arrayOfUnit[0]; //    minTemp 
        startupData[5] = " " + min1DayAgo.arrayOfValue[1] + " " + min1DayAgo.arrayOfUnit[1];//     minWindSped 
        startupData[6] = " " + min1DayAgo.arrayOfValue[2] + " " + min1DayAgo.arrayOfUnit[2];//     minAirPressure  
        startupData[7] = " " + min1DayAgo.arrayOfValue[3] + " " + min1DayAgo.arrayOfUnit[3];//     minRainfall
        // Main fields

        var getLatestTempObj        = await webServiceObj.GetLatestDataAsync("umtTemp1");
        var getLatestWindObj        = await webServiceObj.GetLatestDataAsync("umtWindSpeed");
        var getLatestwindDirObj     = await webServiceObj.GetLatestDataAsync("umtAdjWinDir");
        var getLatestairPressureObj = await webServiceObj.GetLatestDataAsync("umtAdjBaromPress");

        startupData[8] = " " + getLatestTempObj.Value + " " + getLatestTempObj.Unit;//temperatureMainTxtBlock.Text
        startupData[9] = " " + getLatestWindObj.Value + " " + getLatestWindObj.Unit;//temperatureMainTxtBlock.Text
        startupData[10] = "" + getLatestwindDirObj.Value; //temperatureMainTxtBlock.Text
        startupData[11] = " " + getLatestairPressureObj.Value + " " + getLatestairPressureObj.Unit;//temperatureMainTxtBlock.Text
        startupData[12] = "Last update: " + getLatestwindDirObj.Timestamp;//temperatureMainTxtBlock.Text
        **//pass the webservice data to the global variable
        (App.Current as App).NavigateData = startupData;**

        //since im using extendes splash screen i reset the navigation history so the user cannot go back to the extended splash screen      
        this.Frame.SetNavigationState(e.Parameter as string);
        //Go to mainpage
        this.Frame.Navigate(typeof(MainPage));
    }
}

MainPage: in the Mainpage i display the global data loaded by the extended splash screen in textboxes.

public sealed partial class MainPage : weather.Common.LayoutAwarePage
    {
        //Defining objects use through this page
        maxMinSelector maxMinButtonSelector = new maxMinSelector();

        parameterItem max1DayAgo = new parameterItem();
        parameterItem min1DayAgo = new parameterItem();

        parameterItem max1WeekAgo = new parameterItem();
        parameterItem min1WeekAgo = new parameterItem();

        parameterItem max1MonthAgo = new parameterItem();
        parameterItem min1MonthAgo = new parameterItem();

        EasingDoubleKeyFrame keyFrame = new EasingDoubleKeyFrame();

        public MainPage()
        {
            this.InitializeComponent();
            Loaded += MainPage_Loaded;


             Code
         ------------------
         ------------------
         ------------------
         ------------------
            //Cache the page     
            this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
        }


        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
             Code
            ------------------
         ------------------
         ------------------
         ------------------
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {

            // HERE i use the global data initialised in the extended splash screen
            base.OnNavigatedTo(e);
            maxTempTextblock.Text = (App.Current as App).NavigateData[0];
            maxWindSpedTextBlock.Text = (App.Current as App).NavigateData[1];
            maxAirPressureTextBlock.Text = (App.Current as App).NavigateData[2];
            maxRainfallTextBlock.Text = (App.Current as App).NavigateData[3];

            minTempTextblock.Text = (App.Current as App).NavigateData[4];
            minWindSpedTextBlock.Text = (App.Current as App).NavigateData[5];
            minAirPressureTextBlock.Text = (App.Current as App).NavigateData[6];
            minRainfallTextBlock.Text = (App.Current as App).NavigateData[7];


            temperatureMainTxtBlock.Text = (App.Current as App).NavigateData[8];
            WindSpeedTxtBlockLower.Text = (App.Current as App).NavigateData[9];
            WindDirectionTxtBlockLower.Text = (App.Current as App).NavigateData[10];
            airPressureTxtBlockLower.Text = (App.Current as App).NavigateData[11];
            LastUpdateTextField.Text = (App.Current as App).NavigateData[12];


        }

        Code
          ------------------
         ------------------
         ------------------
          ------------------
         ------------------
         ------------------
         ------------------

          ------------------
         ------------------
         ------------------
         ------------------

         ------------------



    }
1

1 Answers

1
votes

This isn't really the answer to your exact question but there is a great video from Build 2012 about startup responsiveness and XAML performance that might touch a bit on what you are asking. He does talk a bit about how to handle apps that have a lot of startup chores.

http://channel9.msdn.com/Events/Build/2012/4-103