[Windows 10] Extension SDK: 讓同一隻應用程式能在不同裝置上執行的秘密

微軟在今年三月揭示了未來的 Universal Apps,將能在各種不同裝置上執行的願景。這些裝置包含了 PC, Mobile, IoT 裝置, Xbox, Surface Hub, 甚至 HoloLens

Gallo blog 1 v2

那麼,要如何讓同一隻 Universal App 在這些不同的裝置上執行呢? Extension SDK 即是解答之一。

以往的作法是什麼?

我們先檢視一下在 Windows 8/8.1 上,欲同時開發 Windows Store App 及 Windows Phone App 的方法。我們可以將共享的程式碼 (如 Business Logic, Data Model, etc.) 實作於 Shared Projects 中,開發者只需額外處理如螢幕大小等 User Experience 上的不同。

但是,編譯之後將會產出兩份針對不同裝置的 Binary or Package,必需分別上傳至不同的 Store 作審核、也必需在不同的 Dev Center 之中作管理:

image

另一個開發者會面對到的問題是,當有些 API 只適用於某些裝置時,要如何處理呢? 例如 :Windows Phone 手機上的實體 Back 鍵、Xbox One 的遙控器、HoloLens 的互動控制等,都不會出現在 Windows 平板上:

image

常見的處理方式即是 Compilation directives,透過 #if 語法,讓開發工具在編譯 (compile) 期間即決定某功能是否會被引入:

image

小結以上:

  • 現有作法會根據不同的裝置,編譯成數個不同的 Binary,也增加了應用程式管理及維護上的負擔;
  • 同時,#if 的作法是在編譯 (compile) 階段即需決定是否引入某些裝置上的功能,亦即無法在執行 (runtime) 階段動態決定。

簡介 Extension SDK:

Windows 10 的 Extension SDK 即是要達成同一個應用程式 (Binary) 能執行在不同裝置上的解決方案:

  1. 它是既有 UAP (Universal Applications Platform) 的延伸、
  2. 針對不同的裝置,即會有不同的 Extension SDK、
  3. 正因為如此,個別的 Extension 即能各自更新其版本

image

如下圖。不同的裝置上都跑著 Windows Core,提供諸如 File I/O, Drivers 等基礎服務;UAP 則提供了一些通用型的控制項,也就是一群 API 的集合,作為通用型應用程式開發的基礎:

image

而在特定裝置上才提供的 APIs,則以 Extension SDK 的方式來實作,表現在圖中的話,即是以延伸的方式由 UAP 的通用型 APIs 再向外擴展:

image

實作 Extension SDK:

1. 透過 Project > Add Reference > Universal App Platform > Extensions ,即可新增您所需要的 Extension 至專案之中。各位可注意到其後有版本別,亦即可各自分別更新並被引入:

image

2. 接下來,即可於程式中使用 Windows.Foundation.Metadata.ApiInformation 這個 Class,在執行 (runtime) 期間判斷某 API 是否存在:

image

若您只想實作一小部份的 APIs,可以考慮直接使用 ApiInformation.IsTypePresent:

 // Note: Cache the value instead of querying it more than once.
 bool isHardwareButtonsAPIPresent =
     Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons");
  
 if (isHardwareButtonsAPIPresent)
 {
     Windows.Phone.UI.Input.HardwareButtons.CameraPressed +=
         HardwareButtons_CameraPressed;
 }

以上程式中,我們只需驗證此裝置是否支援 HardwareButtons 這個 class,若支援,則必定亦包含 CameraPressed 這個事件,我們即可放心的使用它。

當然,除了 IsTypePresent,我們也可使用 IsEventPresent, IsMethodPresent, IsPropertyPresent 測試個別的事件、方法、參數等是否存在:

 bool isHardwareButtons_CameraPressedAPIPresent =
     Windows.Foundation.Metadata.ApiInformation.IsEventPresent
         ("Windows.Phone.UI.Input.HardwareButtons", "CameraPressed");

小結:

  • Extension SDK 成為 Windows 10 UAP 的開發架構中,達成同時支援多種不同裝置的一步活棋。由於是以延伸方式向外作擴增,其保有隨著各裝置的進化而各自演進版本的彈性。
  • 對於開發者而言,能夠簡單的在執行階段 (runtime) 判斷特定裝置上的 API 是否存在,方便達到讓同一隻應用程式執行在不同裝置上的目標。
  • 最後,由於可以僅產出一份 Binary,即能達到 One Store + One Dev Center 的目標,減少開發者的後續維護及管理成本。

另請注意,Extension SDK 的目的並非取代 #if 的功能,Compilation directives 的方式仍然是可行的!

註:

若要嘗試這些新功能:

  1. 請加入 Windows Insider Program,取得並安裝 Windows 10 Developer Preview.
  2. 取得並安裝 Visual Studio 2015 CTP. (目前版本為 CTP6)
  3. 新專案中即會出現 Windows 10 Universal App 的範本。

同時:

1. 若您在測試過程中遇到問題:

2. 若您對 API 有任何新功能的需求,則可透過 Windows platform developer UserVoice site 來建議,這網站會在 BUILD 2015 前持續更新,反應最新的 API 功能。

延伸閱讀:

  1. Developer's Guide to Windows 10 Preview: (04) Extension SDKs (英文教學影片)https://channel9.msdn.com/Series/Developers-Guide-to-Windows-10-Preview/04 

  2. Guide to Windows universal apps: https://msdn.microsoft.com/en-us/library/dn894631.aspx