您的位置:首页 > 移动开发

【windows8开发】Metro App生命周期之启动

2012-08-30 11:01 393 查看
前文介绍过Metro App的生命周期中的各个状态(NotRunning, Running, Suspended)以及概要性的说明了程序的启动,挂起,恢复,关闭等概念,而在本文中会通过相关代码,着重介绍Metro App在启动时的一些细节。本文中的示例代码会使用C++,因为都是基于WinRT,所以Javascript的实现的原理应该是类似的,如果有希望具体了解Javascript的实现方式的,可以在回复中留言。

前文中提到过,当用户启动Metro程序时,程序并不会马上进入Running状态,开始只是NotRunning状态,如果在此状态中程序发生异常导致crash或者被Suspended,则该程序会被终止而不会保留在内存中。从NotRunning状态切换到Running状态过程中,程序会显示一个splash
screen,其实就是一张启动时等待用的图片,如下图:



在VS工程的manifest(.appxmanifest)文件中可以修改希望显示的splash图片,



显示Splash后,程序开始启动,这意味着可以开始执行程序的一些初始化工作,比如设定初期显示页面,事件绑定等。那么,在哪里能执行这些处理呢?在新建C++ Metro程序的工程后,可以看到有个App.xaml.h文件,里面会override一个OnLaunched方法,启动时,onLaunched方法会被调用,看下这个方法的具体实现:

void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ pArgs)
{
     if (pArgs->PreviousExecutionState == ApplicationExecutionState::Terminated)
     {
          //TODO: Load state from previously suspended application
     } else {
          ......
     }
     // Create a page which is defined in MainPage.xaml
     auto page = ref new MainPage();

     // Place the page in the current Window and ensure that it is active
     Window::Current->Content = page;
     Window::Current->Activate();
}


在OnLaunched中可以通过其参数的PreviousExecutionState属性来获得程序之前的执行状态,被正常关闭了,还是被挂起了,还是被强制终止了等等,在Windows::ApplicationModel::Activation::ApplicationExecutionState中定义了这些状态的值。程序可以根据之前状态的值执行相应的操作,一般的逻辑如下:
PreviousExecutionState值为Running, 则还原数据

PreviousExecutionState值为ClosedByUser或NotRunning,则使用默认数据启动
PreviousExecutionState值为Running或Suspend,则一般不需要额外处理(Suspended后被Resume时,其实正常情况下OnLaunched并不会被调用)

由于程序被Suspended后系统可能会在一些情况下强制终止(Terminate)该程序,所以在PreviousExecutionState值为Terminated时,程序可以恢复之前Suspended时保存的数据和状态(在后续的文章《【windows8开发】Metro
App生命周期之Suspended与Resume》中会详细讨论Suspend时如何保存当前状态,Resume时如何恢复等细节)。之后,还创建了MainPage.xaml中定义的UI page,并且设置为当前页,同时通过Activate函数来激活UI。

这里或许有人会有这样的疑问,从App.xaml.h来看,App这个类没有继承于任何类,那为什么会说override了OnLaunched方法呢?其实VS会根据工程中的App.xaml的配置另外生成App.g.h和App.g.cpp,在其中通过C++ /CX的关键字partial扩展定义了App类(编译的时候会跟App.xaml.h中的内容合并),而在App.g.h中可以看出,App类是继承于Windows::UI::Xaml::Application的,因此才有override一说。

另外,在Windows::UI::Xaml::Application中,还有一个方法OnActivated方法可以被重载,这里容易被误解的是,很多人会认为启动时OnActivated也会被触发,其实在程序一般的启动过程(用户正常打开程序)中,即使你重载了OnActivated方法,它也不会被调用,会被触发的只有OnLaunched方法,而OnActivated方法只有在一些特殊的启动过程中才会触发Activate事件,比如用户在另外一个程序中希望通过本程序来执行相关检索而启动本程序时,也就是非直接启动时。

还有一点需要注意的是,在OnLaunched方法中,程序初始化的过程必须在短时间(几秒)内完成,如果初始化处理会花费较长时间,比如需要连接远程网络,读取大数据块等,那么怎么来解决这个问题呢?
这里提供一种解决方案,首先在OnLaunched方法中不进行上述费时的处理,可以考虑在其中把程序设定好的Splash的图片在OnLaunched中通过自己的代码让它继续显示出来,让用户感觉到程序还在初始化过程中(其实程序已经执行完OnLaunched了)。

// Create a page which is defined in SplashPage.xaml
auto splashPage = ref new SplashPage();

// Place the customized splash page in the current Window and ensure that it is active
Window::Current->Content = splashPage;
Window::Current->Activate();


SplashPage是我们在新建的SplashPage.xaml中定义的Page,其内容可以跟工程设定的Splash Screen一样显示同一张图片,当然也可以根据需要设定为其他内容。在splashPage中可以绑定事件,通过异步任务来执行那些我们需要的长时间初始化的操作,当初始化执行完成后,触发事件来从SplashPage切换到程序的初始页面。

最后,总结一下,程序启动时,会先显示一个Splash Screen,期间程序在override的Application::OnLaunched方法中会基于之前的运行状态执行相应的处理以及一些其他的初始化工作,初始化完成后会显示初始UI,这就是Metro程序的启动过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: