天天看點

【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目錄下,請看截圖:

【Win 10應用開發】認識一下UAP項目

是吧,都是以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項目,然後打開對象浏覽器視窗,然後過濾條件選擇 我的解決方案 ,然後你看看是不是有這三個子集。

【Win 10應用開發】認識一下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的,然後看視窗中間部分,不多,就那麼幾個。看圖

【Win 10應用開發】認識一下UAP項目

看到沒,這些項目模闆名字的後面都有UAP辨別。分别為标準應用程式(空白應用程式)、類庫(*.dll)、Windows運作時元件(*.winmd)、單元測試。

要建一個可以執行的應用程式,當然要選标準應用程式了。

建立項目後,在解決方案資料總管中看到很熟悉的檔案結構,是吧,我沒騙你吧,隻要你懂Win8.1/WP 8.1的應用開發,這個10的UAP也可以無需學習任何知識就能刷刷刷地寫了。

【Win 10應用開發】認識一下UAP項目

App就是表示目前應用程式的類,從Application派生,MainPage當然是首頁面類了,這都和以前一樣,一切都是很熟悉了。

現在,大家打開MainPage.xaml,看看這個新的XAML設計器。如圖

【Win 10應用開發】認識一下UAP項目

如何,還是很熟悉吧。

因為現在的UAP已經合并到一個項目中了,而這個UAP項目是可以直接在PC桌面、Windows平闆、WP手機、xBox遊戲機等裝置上運作的,是以請你注意觀察XAML設計器視窗的左上角,看到那下拉菜單了嗎?試試看,不用我介紹了,你一定會用。

【Win 10應用開發】認識一下UAP項目

是啊,這個菜單就讓你選擇不同尺寸的裝置,然後可以預覽一下界面效果。

而在調試運作按鈕的下拉菜單中,已經有本地計算機,遠端計算機(平闆電腦的真機可以用這項),以及WP 10的模拟器。如果想在WP 10真實手機上調試就選Device。

【Win 10應用開發】認識一下UAP項目

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

代碼寫着寫着,不免又發現一個問題了,既然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的目錄?然後你打開看看,你馬上就會明白了。

【Win 10應用開發】認識一下UAP項目

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就行了。

【Win 10應用開發】認識一下UAP項目

這時候,就可以處理“回退”鍵了。

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開發相關的内容。

繼續閱讀