none
cómo disminuir el tiempo de inicio de mi app?? RRS feed

  • Pregunta

  • Hola que tal buen día me podrian ayudar con el tema del tiempo que se toma mi apps para iniciar ?... como podria disminuir este tiempo dado que la quise ya subir al store y le hice el test con el kit manager y me salio un error en el tiempo de inicio dado que se toma casi 7 segundos para iniciar y me dice que el tiempo minimo es 5 segundos, gracias por la ayuda, y la forma en la cual se descarga la informacion para mostrar es mediante archivos publicados las imagenes y la data la consume desde internet..

    gracias.. buen dia

    lunes, 12 de noviembre de 2012 15:33

Respuestas

  • Hola aqui tengo la solución con la que logré esto, en principio estaba buscando soluciones mediante mayor uso de procesador, memoria, lectura de disco, pero la solucion tiene que trabajar en distintos procesadores tal es asi que cabe la posibilidad que trabaje sobre ARM y ésto no es recomendable, así que opte por usar el splash screen extended...

    bueno aquí la solución:

    primero creamos el archivo que sera la extensión y le damos un formato parecido a la pantalla de inicio para que el efecto de cambio de pantalla entre una y otra no sea tan brusca aquí el XML:

    <Page x:class....."propiedades de la pagina".........>

    <Canvas Background="#F6F6F6">
            <Image x:Name="SplashImage" Stretch="None" Source="/Assets/SplashScreen.png"/>
            <ProgressRing x:Name="Progress" IsActive="True" IsEnabled="True" Foreground="#00A9D9" Height="40" Width="40"/>
        </Canvas>

    </Page>

    este es el codigo de ésta pagina:

                                

        public sealed partial class ExtendedSplash : Page
        {
            private SplashScreen _splash;
            private bool _dismissed = false;
            LaunchActivatedEventArgs _activationArgs = null;

            public ExtendedSplash(SplashScreen splash, bool dismissed, LaunchActivatedEventArgs activationArgs)
            {
                _splash = splash;
                _dismissed = dismissed;
                _activationArgs = activationArgs;

                Loaded += ExtendedSplash_Loaded;
                Window.Current.SizeChanged += Current_SizeChanged;
                this.InitializeComponent();
                PositionElements();
            }

            private void PositionElements()
            {
                SplashImage.SetValue(Canvas.LeftProperty, _splash.ImageLocation.X);
                SplashImage.SetValue(Canvas.TopProperty, _splash.ImageLocation.Y);
                SplashImage.Height = _splash.ImageLocation.Height;
                SplashImage.Width = _splash.ImageLocation.Width;

                var topWithBuffer = _splash.ImageLocation.Y + _splash.ImageLocation.Height + 20;
                var middle = _splash.ImageLocation.X + (_splash.ImageLocation.Width / 2) - 30;

                Progress.SetValue(Canvas.TopProperty, topWithBuffer);
                Progress.SetValue(Canvas.LeftProperty, middle);
            }

            async void ExtendedSplash_Loaded(object sender, RoutedEventArgs e)
            {
                var rootFrame = new Frame();
                try
                {//para hacer la carga primero verifico la conexion y despues hago una carga remota o local.. eso es parte de la solución que propuse para la aplicacion se podría dar solo la carga remota si es su caso y no tendrian que verificar la conexión de internet

            string estadoConneccion = VerificarConexionInternet.verificarConexionInternet(null);
                    if (estadoConneccion == "conectado")
                    {
                        await ((App)Application.Current).DataSourceCPr.LoadRemoteDataAsync();                    
                    }
                    else
                    {
                        await ((App)Application.Current).DataSourceCPr.LoadLocalDataAsync();                   
                    }

                    rootFrame.Navigating += rootFrame_Navigating;
                    SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
                    if (_activationArgs.PreviousExecutionState == ApplicationExecutionState.Terminated)
                    {
                        await SuspensionManager.RestoreAsync();
                    }

                    if (rootFrame.Content == null)
                    {
                        if (!rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups"))
                        {
                            throw new Exception("Error al crear la pagina incial");
                        }
                    }

                    Window.Current.Content = rootFrame;
                }
                catch (Exception)
                {
                    var messageDialog = new Windows.UI.Popups.MessageDialog("Hubo un error al descargar la información. Por favor verifica tu conexión y reinicia la aplicación.");
                    var result = messageDialog.ShowAsync();
                }

                Window.Current.Activate();
            }

            void rootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
            {
                ((App)Application.Current).NavigatedPage = e.SourcePageType;            
            }

            void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
            {
                if (null != _splash)
                {
                    PositionElements();
                }
            }

            internal void DismissedEventHandler(SplashScreen sender, object e)
            {
                _dismissed = true;
            }

            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
        }
    }

    lunes, 19 de noviembre de 2012 14:45
  • no sé si esto sea recomendable pero la respuesta la pondré en varios post porque al parecer hay un límite de caracteres  en el comentario.. sigamos...

    éste es el codigo del App.cs

            

    sealed partial class App : Application
        {
            public App()
            {
                this.InitializeComponent();
                this.Suspending += OnSuspending;
            }

            private DataItem _item;

            public static App Instance
            {
                get { return ((App)Current); }
            }

            public Type NavigatedPage { get; set; }

            public  DataSource DataSourceCPr { get; private set; }

            public DataGroup CurrentGroup { get; set; }

            public DataItem CurrentItem
            {
                get { return _item; }
                set
                {
                    if (value != null)
                    {
                        DataItem item = DataSourceCPr.GetItem(value.UniqueId);
                        CurrentGroup = item.Group;
                    }
                    _item = value;
                }
            }

    protected async override  void OnLaunched(LaunchActivatedEventArgs args)
            {

        DataSourceCPr = new DataSource();

                if (args.PreviousExecutionState == ApplicationExecutionState.Running)
                {
                    Window.Current.Activate();
                    return;
                }
                
                TileUpdateManager.CreateTileUpdaterForApplication().EnableNotificationQueue(true); // mostrar los ultimos 5 tiles
                TileUpdateManager.CreateTileUpdaterForApplication().StartPeriodicUpdate(new Uri("xmlparaextraereltile.xml"), PeriodicUpdateRecurrence.HalfHour);
                var splashScreen = args.SplashScreen;
                var eSplash = new ExtendedSplash(splashScreen, false, args);
                splashScreen.Dismissed += eSplash.DismissedEventHandler;
                Window.Current.Content = eSplash;
                Window.Current.Activate();
            }

    private async void OnSuspending(object sender, SuspendingEventArgs e)
            {
                var deferral = e.SuspendingOperation.GetDeferral();
                await SuspensionManager.SaveAsync();
                deferral.Complete();
            }

    }

    bueno eso sería toda la solución para la parte de poner un extended splash.... buen día cualquier consulta la hacen llegar.. 

    lunes, 19 de noviembre de 2012 14:52

Todas las respuestas

  • Hola Rangel.

    Haz uso de las Extended Splash Screen http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868191.aspx

    Otro enlace http://www.c-sharpcorner.com/UploadFile/99bb20/extended-splash-screen-in-metro-style-application/

    Ejemplo de código http://code.msdn.microsoft.com/windowsapps/Splash-screen-sample-89c1dc78/


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento"
    MCTS | SharePoint 2010, Application Development
    MCTS | SharePoint 2010, Configuring
    Twitter | @saintwukong

    lunes, 12 de noviembre de 2012 15:43
  • Hola que tal, no me queda muy claro de como implementar el splash screen usando un progress ring; de que forma puedo implementar ésto, de tal forma que cuando acabe de cargar mi data; me lance  la pantalla del hub principal de mi app ?.. gracias por la respuesta  y el posible ejemplo..
    viernes, 16 de noviembre de 2012 16:52
  • Por lo que tengo entendido se usa Extended Splash Screen cuando hay que carga datos (como en tu caso) y lo que se hace es una pantalla igual al Splash Screen con algún indicador de carga. Casi todas las aplicaciones que cargan datos por internet suelen usar un Extended Splash Screen.

    Resumido de forma más clara.

    1 -> El Splash Screen no puede tardar más de 5 segundos, pero el Extended Splash Screen sí.

    2 ->  Tiene que hacer un redirecionamiento de Splash Screen para Extended Splash Screen (aquí cargas los datos) intenta usar la misma pantalla que la de Splash Screen.

    3-> Una vez que tenga los datos haces un redirecionamiento.

    Si te fijas en la aplicación de el país, puedes observar que hace el mismo proceso.

    un saludo

       

     

    Elbrinner

    viernes, 16 de noviembre de 2012 17:37
  • Hola Elbrinner; claro estas en lo cierto pero actualmente estoy viendo como hacer para hacer el redireccionamiento; como valido que los datos ya cargaron ?.. gracias de antemano por la respuesta y como seria el comportamiento de la app si se llegase a suspender ?..... gracias por la pronta respuesta.. me dices el ejemplo del EL PAIS ?... cual es ese ejemplo, tendras algún enlace ?

    Saludos Rubén...

    viernes, 16 de noviembre de 2012 18:58
  • Hola Elbrinner; claro estas en lo cierto pero actualmente estoy viendo como hacer para hacer el redireccionamiento; como valido que los datos ya cargaron ?.. gracias de antemano por la respuesta y como seria el comportamiento de la app si se llegase a suspender ?..... gracias por la pronta respuesta.. me dices el ejemplo del EL PAIS ?... cual es ese ejemplo, tendras algún enlace ?

    Saludos Rubén...

    Fíjate en cualquiera aplicación que carga datos que ya viene instalado con Windows 8( puede ser la de noticia y de deporte). Cuando abres la aplicación los 3 primeros segundos no muestra la imagen cargado (icono redondo de carga abajo en el medio) pasados 3 segundos muestra la misma imagen con este icono. En este momento está en otra página(Extended Splash Screen).

    Nunca implemente esto, pero en todo proceso de carga hay un evento que es el COMPLETO. En WP7 seria algo parecido a esto:

    WebClient webhoy = new WebClient();
     string uriHoy = "http://www.misdatos.com";
      webhoy.DownloadStringAsync(new Uri(uriHoy));
     webhoy.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webhoy_DownloadStringCompleted);

    void webhoy_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
       {

    // Ya tengo los datos, redirección para la aplicación.

    }

      

    Elbrinner

    viernes, 16 de noviembre de 2012 20:12
  • Hola si entiendo cual es el efecto que se logra pero estaba buscando como resolver eso y encontre este enlace http://www.c-sharpcorner.com/UploadFile/99bb20/extended-splash-screen-in-metro-style-application/ el cual me parece que puede servir pero aun me estoy perdiendo en unos temas... no se si alguien pudiese ayudarme con esta parte, lo que me falta evaluar es que ya se cargaron los datos para lanzar a la pagina principal.. un ejemplo simple seria hacerlo para la plantilla que genera cuando creas una app con el VS.. gracias de antemano por la ayuda...
    sábado, 17 de noviembre de 2012 14:55
  • Hola rangelvilca.

    Voy a publicarte un ejemplo en cuanto tenga un rato para que puedas comprobar cómo se hace.


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento"
    MCTS | SharePoint 2010, Application Development
    MCTS | SharePoint 2010, Configuring
    Twitter | @saintwukong

    sábado, 17 de noviembre de 2012 17:24
  • Hola rangelvilca. Puedes usar las ExtendedSplashScreen o simplemente puedes hacer que tu aplicación muestre unos controles diferentes (o una página diferente) antes de cargar y después de cargar la información que consideras necesaria para que comience a "funcionar". Lo que importa para que la aplicación sea validada, es que separes de la iniciación, la carga de datos externos. El cómo le presentes este proceso al usuario da un poco igual.

    Saludos.

    lunes, 19 de noviembre de 2012 3:16
  • Hola, logre solucionar ésto, gracias a todos por la ayuda.. luego estaré subiendo el código utilizado por si otra persona se encuentra en el mismo caso.. gracias nuevamente...
    lunes, 19 de noviembre de 2012 6:45
  • Hola aqui tengo la solución con la que logré esto, en principio estaba buscando soluciones mediante mayor uso de procesador, memoria, lectura de disco, pero la solucion tiene que trabajar en distintos procesadores tal es asi que cabe la posibilidad que trabaje sobre ARM y ésto no es recomendable, así que opte por usar el splash screen extended...

    bueno aquí la solución:

    primero creamos el archivo que sera la extensión y le damos un formato parecido a la pantalla de inicio para que el efecto de cambio de pantalla entre una y otra no sea tan brusca aquí el XML:

    <Page x:class....."propiedades de la pagina".........>

    <Canvas Background="#F6F6F6">
            <Image x:Name="SplashImage" Stretch="None" Source="/Assets/SplashScreen.png"/>
            <ProgressRing x:Name="Progress" IsActive="True" IsEnabled="True" Foreground="#00A9D9" Height="40" Width="40"/>
        </Canvas>

    </Page>

    este es el codigo de ésta pagina:

                                

        public sealed partial class ExtendedSplash : Page
        {
            private SplashScreen _splash;
            private bool _dismissed = false;
            LaunchActivatedEventArgs _activationArgs = null;

            public ExtendedSplash(SplashScreen splash, bool dismissed, LaunchActivatedEventArgs activationArgs)
            {
                _splash = splash;
                _dismissed = dismissed;
                _activationArgs = activationArgs;

                Loaded += ExtendedSplash_Loaded;
                Window.Current.SizeChanged += Current_SizeChanged;
                this.InitializeComponent();
                PositionElements();
            }

            private void PositionElements()
            {
                SplashImage.SetValue(Canvas.LeftProperty, _splash.ImageLocation.X);
                SplashImage.SetValue(Canvas.TopProperty, _splash.ImageLocation.Y);
                SplashImage.Height = _splash.ImageLocation.Height;
                SplashImage.Width = _splash.ImageLocation.Width;

                var topWithBuffer = _splash.ImageLocation.Y + _splash.ImageLocation.Height + 20;
                var middle = _splash.ImageLocation.X + (_splash.ImageLocation.Width / 2) - 30;

                Progress.SetValue(Canvas.TopProperty, topWithBuffer);
                Progress.SetValue(Canvas.LeftProperty, middle);
            }

            async void ExtendedSplash_Loaded(object sender, RoutedEventArgs e)
            {
                var rootFrame = new Frame();
                try
                {//para hacer la carga primero verifico la conexion y despues hago una carga remota o local.. eso es parte de la solución que propuse para la aplicacion se podría dar solo la carga remota si es su caso y no tendrian que verificar la conexión de internet

            string estadoConneccion = VerificarConexionInternet.verificarConexionInternet(null);
                    if (estadoConneccion == "conectado")
                    {
                        await ((App)Application.Current).DataSourceCPr.LoadRemoteDataAsync();                    
                    }
                    else
                    {
                        await ((App)Application.Current).DataSourceCPr.LoadLocalDataAsync();                   
                    }

                    rootFrame.Navigating += rootFrame_Navigating;
                    SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
                    if (_activationArgs.PreviousExecutionState == ApplicationExecutionState.Terminated)
                    {
                        await SuspensionManager.RestoreAsync();
                    }

                    if (rootFrame.Content == null)
                    {
                        if (!rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups"))
                        {
                            throw new Exception("Error al crear la pagina incial");
                        }
                    }

                    Window.Current.Content = rootFrame;
                }
                catch (Exception)
                {
                    var messageDialog = new Windows.UI.Popups.MessageDialog("Hubo un error al descargar la información. Por favor verifica tu conexión y reinicia la aplicación.");
                    var result = messageDialog.ShowAsync();
                }

                Window.Current.Activate();
            }

            void rootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
            {
                ((App)Application.Current).NavigatedPage = e.SourcePageType;            
            }

            void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
            {
                if (null != _splash)
                {
                    PositionElements();
                }
            }

            internal void DismissedEventHandler(SplashScreen sender, object e)
            {
                _dismissed = true;
            }

            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
        }
    }

    lunes, 19 de noviembre de 2012 14:45
  • no sé si esto sea recomendable pero la respuesta la pondré en varios post porque al parecer hay un límite de caracteres  en el comentario.. sigamos...

    éste es el codigo del App.cs

            

    sealed partial class App : Application
        {
            public App()
            {
                this.InitializeComponent();
                this.Suspending += OnSuspending;
            }

            private DataItem _item;

            public static App Instance
            {
                get { return ((App)Current); }
            }

            public Type NavigatedPage { get; set; }

            public  DataSource DataSourceCPr { get; private set; }

            public DataGroup CurrentGroup { get; set; }

            public DataItem CurrentItem
            {
                get { return _item; }
                set
                {
                    if (value != null)
                    {
                        DataItem item = DataSourceCPr.GetItem(value.UniqueId);
                        CurrentGroup = item.Group;
                    }
                    _item = value;
                }
            }

    protected async override  void OnLaunched(LaunchActivatedEventArgs args)
            {

        DataSourceCPr = new DataSource();

                if (args.PreviousExecutionState == ApplicationExecutionState.Running)
                {
                    Window.Current.Activate();
                    return;
                }
                
                TileUpdateManager.CreateTileUpdaterForApplication().EnableNotificationQueue(true); // mostrar los ultimos 5 tiles
                TileUpdateManager.CreateTileUpdaterForApplication().StartPeriodicUpdate(new Uri("xmlparaextraereltile.xml"), PeriodicUpdateRecurrence.HalfHour);
                var splashScreen = args.SplashScreen;
                var eSplash = new ExtendedSplash(splashScreen, false, args);
                splashScreen.Dismissed += eSplash.DismissedEventHandler;
                Window.Current.Content = eSplash;
                Window.Current.Activate();
            }

    private async void OnSuspending(object sender, SuspendingEventArgs e)
            {
                var deferral = e.SuspendingOperation.GetDeferral();
                await SuspensionManager.SaveAsync();
                deferral.Complete();
            }

    }

    bueno eso sería toda la solución para la parte de poner un extended splash.... buen día cualquier consulta la hacen llegar.. 

    lunes, 19 de noviembre de 2012 14:52
  • Hola Rangelvilca.

    Por fin saqué tiempo para publicar el artículo que te comenté.

    http://geeks.ms/blogs/santypr/archive/2012/12/14/windows-8-store-apps-usar-extended-splash-screen-para-cargas-de-datos-iniciales.aspx


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento"
    MCTS | SharePoint 2010, Application Development
    MCTS | SharePoint 2010, Configuring
    Twitter | @saintwukong

    sábado, 15 de diciembre de 2012 17:23