【Win 10应用开发】认识一下UAP项目

Windows 10 SDK预览版需要10030以上版本号的Win 10预览版系统才能使用。之前我安装的9926的系统,然后安装VS 2015 CTP 6,再装Win 10 SDK,但是在新建项目后,打开XAML文件时,XAML设计器无法正常注册。

后来,我在SDK目录下的描述API协定的xml文件中看到,对系统的版本要求是在10030以上。所以,应该安装3月份的预览版,即10041以上的版本就能正常使用XAML设计器了。

在VS的使用过程,如果出现错误,不要急着发狂,因为那样做除了伤身之外别无好处。

1、可以网上搜搜,看看有没有现成的解决方法。

2、应该关注在出错时提示的错误信息,在其中总能找到一些提示的,至少也能推断造成问题的来源。

3、可以多试几次,看看错误是在你进行什么操作的时候发生,缩小排查范围。

4、查看日志。

5、检查系统是否被动过手脚。用于开发的机器,平时还是少装一些不三不四的软件;也少用一些不干不净的系统镜像。

做到以上各点,至少会减少一些灵异事件的发生。从Vista开始,系统自身功能比较完善,也不需要所谓的第三方优化工具,任何的非系统的优化工具只会破坏系统,污染环境。更何况,少装这些软件,性能也会提升好几倍,这些所谓的优化工具本身就是个流氓。

 

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

刚才提到了在SDK的安装目录下有个描述API协定的xml文件,路径就在C:\Program Files (x86)\Windows Kits\10,这是默认路径,我一向安装开发工具都是放在默认路径下的,这样可以大大降低灵异事件的发生率。所以在系统盘分区时,给多大空间大家看着办吧。我分的C盘是92GB,其实也用不完,只是宁可大一点也不要少了。我的盘子是500G,但我知道,现在的电脑的盘子都是用T来计算了,所以,大家别吝啬你的空间,用不完也是白糟踏。

那个xml文件名为SDKManifest.xml,我们看看它里面有啥。

<FileList
  DisplayName = "Universal App Platform"
  PlatformIdentity = "UAP, Version=10.0.10030.0"      
  TargetFramework = ".NETCore,version=v4.5.3;.NETFramework,version=v4.5.3"
  MinVSVersion = "14.0"
  MinOSVersion = "6.1"
  MaxOSVersionTested = "10.0"
  UnsupportedDowntarget = "Windows, version=8.1">

  <File Reference = "Windows">
    <ToolboxItems VSCategory = "Toolbox.Default"/>
  </File>
</FileList>

这个文件不复杂,我们也没有必要非得把里面的所有XML都弄明白,只要知道是怎么回事就可以了。在上面的XML中,重点看以下几项:

1、DisplayName = "Universal App Platform",这说明,Windows 10 app是UAP类型(通用应用)。

2、PlatformIdentity = "UAP, Version=10.0.10030.0",支持的平台标识,看到了吧,版本是10030以上。

3、MinVSVersion = "14.0",只有VS 2015才支持,目前是CTP6。

4、UnsupportedDowntarget = "Windows, version=8.1",不兼容8.1的应用。大家都知道,在8.1时的UAP是分成三个项目的,而10中的UAP是合并为一个的,这样很好,我只管写一个项目就行了,也不用去考虑哪些代码该放在共享项目下,也不必为各个平台都弄一个项目了。这里说的是项目不兼容,但你要明白,在Win 10中,8.1的应用依然可以运行。如果你不需用到Win10的新功能,那你用8.1的项目也行

5、<File Reference = "Windows">表示项目默认引用面向Windows所有平台的UAP库。

 

我这里不是叫大家去记上面的内容,一定要注意,这种东西只供了解,你明天忘了也无所谓,你只需明白UAP是什么就行了。其实我是在向大家分享如何自学的方法,当你拿到一个新玩意儿的时候,不要急着去写程序,先花间去弄明白它是个啥东西也不迟,千万不要被现在社会上流行的浮躁思潮所毒害。

 

看了上面那个xml,至少我们知道:

1、开发10的应用需要系统版本在10030以上。

2、要用新的VS。

3、项目向下不兼容。UAP已经从三个项目变为一个项目,三分天下最终为司马氏的晋朝统一。

 

接下来我们需要知道UAP项目是怎么引用各个API集的。

和以前的store app一样,有一个API子集肯定有的,500%是少不了的,就是.NET for Windows Store apps,这个我就不多说了,都知道的,就可以用于Runtime App的.NET API集。

除了.net子集外,当你新建一个面向Win 10的 UAP 项目后,还会引用三个API子集,这三个API集也是在一个XML文件中指定的,文件位于C:\Program Files (x86)\Windows Kits\10\Platforms\UAP\10.0.10030.0目录下,名字为Platform.xml。

不妨打开看看。

<ApplicationPlatform name="UAP" friendlyName="Universal Application Platform" version="10.0.10030.0">  
   <MinimumVisualStudioVersion>14.0.22213.01</MinimumVisualStudioVersion> 
   <ContainedApiContracts>  
      <ApiContract name="Windows.Foundation.FoundationContract" version="1.0.0.0" />  
      <ApiContract name="Windows.Foundation.UniversalApiContract" version="1.0.0.0" />  
      <ApiContract name="Windows.Networking.Connectivity.WwanContract" version="1.0.0.0" /> 
   </ContainedApiContracts>  
</ApplicationPlatform>  

在UAP应用中,所有API都以子集的形存在,名字都有Contract结尾,它们位于C:\Program Files (x86)\Windows Kits\10\References目录下,请看截图:

是吧,都是以Contract结尾的吧。这样使得每个API子集都有相对的独立性,而且都放在一个目录下,现在1.0.0,以后如果有2.0.0,那直接在目录下建一个2.0.0的子目录,再把*.wimd放进去就行了,方便以后更新,最后再通过一个SDKManifest.xml文件来罗列一些某类型的项目需要XXXXContract、YYYYContract的API就行了。

扯远了,咱们回到Platform.xml文件,从上面的XML中可以看到,一个标准的UAP将默认引用以下三个RT API子集:

Windows.Foundation.FoundationContract,

Windows.Foundation.UniversalApiContract,

Windows.Networking.Connectivity.WwanContract

你不信的话,建一个UAP项目,然后打开对象浏览器窗口,然后过滤条件选择 我的解决方案 ,然后你看看是不是有这三个子集。

 

说不定,以后API升级了,有了2.0.0的UAP项目了,或许把这个XML弄成这样就可以了:

version="10.0.10030.0">  
   <MinimumVisualStudioVersion>14.0.22213.01</MinimumVisualStudioVersion> 
   <ContainedApiContracts>  
      <ApiContract name="Windows.Foundation.FoundationContract" version="2.0.0.0" />  
      <ApiContract name="Windows.Foundation.UniversalApiContract" version="2.0.0.0" />  
      <ApiContract name="Windows.Networking.Connectivity.WwanContract" version="2.0.0.0" /> 
   </ContainedApiContracts>  
</ApplicationPlatform>  

 

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

好,现在你大概知道UAP的API是怎么分布了,现在,再来动手写代码就有头绪了。

在新建UAP项目时,要选择Windows 10的,然后看窗口中间部分,不多,就那么几个。看图

看到没,这些项目模板名字的后面都有UAP标识。分别为标准应用程序(空白应用程序)、类库(*.dll)、Windows运行时组件(*.winmd)、单元测试。

要建一个可以执行的应用程序,当然要选标准应用程序了。

 

新建项目后,在解决方案资源管理器中看到很熟悉的文件结构,是吧,我没骗你吧,只要你懂Win8.1/WP 8.1的应用开发,这个10的UAP也可以无需学习任何知识就能刷刷刷地写了。

 

App就是表示当前应用程序的类,从Application派生,MainPage当然是主页面类了,这都和以前一样,一切都是很熟悉了。

现在,大家打开MainPage.xaml,看看这个新的XAML设计器。如图

如何,还是很熟悉吧。

 

因为现在的UAP已经合并到一个项目中了,而这个UAP项目是可以直接在PC桌面、Windows平板、WP手机、xBox游戏机等设备上运行的,因此请你注意观察XAML设计器窗口的左上角,看到那下拉菜单了吗?试试看,不用我介绍了,你一定会用。

是啊,这个菜单就让你选择不同尺寸的设备,然后可以预览一下界面效果。

 

而在调试运行按钮的下拉菜单中,已经有本地计算机,远程计算机(平板电脑的真机可以用这项),以及WP 10的模拟器。如果想在WP 10真实手机上调试就选Device。

 

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

代码写着写着,不免又发现一个问题了,既然UAP是一个应用项目通杀各种设备,但是,我们知道,PC、平板上是不用“回退”键的,只有WP手机上才有“回退”键,所以在8.1的时候,只有面向WP的应用才能调用Windows.Phone.UI.Input.HardwareButtons类,然后为BackPressed事件添加处理代码,实现侦听“回退”键行为。

于是,我们会在Win 10 UAP项目中也处理该事件,以便当应用在手机上运行时进行处理,当然手机以外其他平台不需要了。可是,当我在代码中使用时,却发现无法引入Windows.Phone.UI.Input命名空间,而且在编译时报错。但是查看对象浏览器时,在UAP Platform的API下又显示支持HardwareButtons类的,怎么会这样呢?是SDK的开发团队搞错了吗?

开发团队当然没弄错了。既然UAP是通用于各个设备的,自然在UAP项目中默认只引用可以在所有平台上都能用的API了,即前面我给大家看的Platform.xml中列出的那三条引用。

现在,大家可以回到SDK的安装目录C:\Program Files (x86)\Windows Kits\10\,有没有看到一个叫Extension SDKs的目录?然后你打开看看,你马上就会明白了。

Windows Desktop表示支持在桌面系统上运行的API子集,其实和UAP子集是一样的,差别在于我们常说的桌面平台是指面向x86、x64架构的CPU的应用,而RT应用还有一个ARM平台的支持。你如果想知道这个Desktop子集有哪些API,可以到里面找到SDKManifest.xml,打开这个XML就看到了。

<FileList TargetPlatform="UAP" TargetPlatformMinVersion="10.0.0.1" TargetPlatformVersion="10.0.10030.0" SDKType="Platform" DisplayName="Windows Desktop Extension SDK" AppliesTo="WindowsAppContainer" MinVSVersion="14.0" ProductFamilyName="Windows.Desktop" SupportsMultipleVersion="Error" TargetFramework=".NETCore, version=v4.5.3;" SupportPrefer32Bit="True" MoreInfo="http://go.microsoft.com/fwlink/?LinkId=517639">
    <ContainedApiContracts>
        <ApiContract name="Windows.ApplicationModel.Activation.ActivatedEventsContract" version="1.0.0.0"/>
        <ApiContract name="Windows.ApplicationModel.Activation.WebUISearchActivatedEventsContract" version="1.0.0.0"/>
        <ApiContract name="Windows.ApplicationModel.Calls.LockScreenCallContract" version="1.0.0.0"/>
        <ApiContract name="Windows.ApplicationModel.Resources.Management.ResourceIndexerContract" version="1.0.0.0"/>
        <ApiContract name="Windows.ApplicationModel.Search.SearchContract" version="1.0.0.0"/>

……

 

同理,还有一个目录叫Windows Mobile的目录,用于WP手机特定的API就放在这里面了,一样的方法,你进去里面找到SDKManifest.xml,打开它,就能看到有哪些API了。

<FileList TargetPlatform="UAP" TargetPlatformMinVersion="10.0.0.1" TargetPlatformVersion="10.0.0.1" SDKType="Platform" DisplayName="Windows Mobile Extension SDK" AppliesTo="WindowsAppContainer" MinVSVersion="14.0" ProductFamilyName="Windows.Mobile" SupportsMultipleVersion="Error" TargetFramework=".NETCore, version=v4.5.3;" SupportPrefer32Bit="True" MoreInfo="http://go.microsoft.com/fwlink/?LinkId=517396">
    <ContainedApiContracts>
        <ApiContract name="Windows.ApplicationModel.Activation.WebUISearchActivatedEventsContract" version="1.0.0.0"/>
        <ApiContract name="Windows.ApplicationModel.Wallet.WalletContract" version="1.0.0.0"/>
        <ApiContract name="Windows.Devices.SmartCards.SmartCardBackgroundTriggerContract" version="1.0.0.0"/>
        <ApiContract name="Windows.Devices.SmartCards.SmartCardDeviceContract" version="1.0.0.0"/>
        <ApiContract name="Windows.Devices.SmartCards.SmartCardEmulatorContract" version="1.0.0.0"/>
……


现在你终于明白这些API子集为啥都以Contract结尾,它就是一套协定,而哪些API通过,哪些API只有特定平台才能用,都通过一些XML文件来配置,管理方便,在更新时也不容易出错。当然,这种协定方案还有一个用途,后面会告诉大家。

 

好了,知道这个道理就好办了,在VS中添加面向手机的API集引用就行了。在添加时,选择UAP Platform节点,然后找到Extension SDKs。勾选Windows Mobile Extension SDK就行了。

这时候,就可以处理“回退”键了。

Windows.Phone.UI.Input.HardwareButtons.BackPressed += OnBack;

但是,问题还没有得到解决,你想啊,UAP是运行在所有设备上的,虽然我们刚才引用了面向手机的API子集,可是如果我这个应用在平板上运行,这行代码照样会被执行,而平板是不支持“回退”按键的,不仅是平板,PC上也没有这个,是吧,一旦在非手机平台运行也会出错啊。

是的,是的,因此在使用一些需要特定平台才能用的API时,要先进行一些验证,如果该API在当前运行的平台上支持就执行,不支持就跳过代码不执行。

所以,把上面代码改为:

            if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
            {
                Windows.Phone.UI.Input.HardwareButtons.BackPressed += OnBack;
            }

刚才在说到API协定时,我说过它还有一个用途的,答案就在这里了。ApiInformation类就是用来验证API的,IsTypePresent方法检测某个类在当前平台上是否支持。支持就返回true,不支持就返回false。注意在指定参数时要写上类型的全路径,包括命名空间的名字。ApiInformation类提供一些静态方法用来检测API的有效性,除了上面用到的检查类型的,也可以用IsMethodPresent方法来检查某个类中某个方法是否可用,等等。

不要觉得这个很麻烦,其实比8.1的UAP通过定义WINDOWS_PHONE_APP这样的条件编译的方法简单多了。再说了,不是说所有API在使用时都这样,只需要验证某个平台特定的API即可,UAP通用的API不用验证。说简单一点,就是在用到Extension SDKs的API子集时才会考虑检查可用性。如果我们不需要用到这些特定API,就不必去引用它们,也不必去进行验证了。记住:只有在用的时候才亮剑

 

好了,老周这篇语无伦次的文章,向大家介绍了Windows 10 UAP项目的基本情况。以后,老周会继续写烂文向大家分享Windows开发相关的内容。

posted @ 2015-04-08 17:31  东邪独孤  阅读(8512)  评论(16编辑  收藏  举报