Windows RT應(yīng)用程序開(kāi)發(fā)介紹培訓(xùn)的講義
如有問(wèn)題歡迎指正。
下載地址:
幻燈片http://files.cnblogs.com/lxconan/WinRTIntroPPT.pdf
附加說(shuō)明http://files.cnblogs.com/lxconan/WinRTIntro.pdf
1 概述
這篇的標(biāo)題叫做Windows RT Introduction而非Windows 8 Introduction是想強(qiáng)調(diào)此次介紹是從開(kāi)發(fā)人員的角度而不是普通用戶(hù)的角度出發(fā)的。同時(shí),我們關(guān)注的是Metro Style應(yīng)用而不是傳統(tǒng)的Win32應(yīng)用程序的開(kāi)發(fā)。
實(shí)際上,使用C#或者HTML + Javascript書(shū)寫(xiě)一個(gè)Hello world應(yīng)用的代碼例子已經(jīng)在網(wǎng)上泛濫了。但是僅有一個(gè)Hello world并不能夠說(shuō)你掌握了Win RT的開(kāi)發(fā)。從Pro的角度來(lái)說(shuō)我們應(yīng)該弄清楚整件事情的細(xì)節(jié)。那么首先就應(yīng)當(dāng)是他的架構(gòu)。這樣寫(xiě)起程序來(lái)才能心定。
2 Windows 8 Metro與Desktop模式
2.1 兩種模式
Windows 8的應(yīng)用程序顯示模式目前有兩種,定義在METRO_MONITOR_MODE中:即傳統(tǒng)的桌面模式(MMM_Desktop)以及Metro模式(MMM_Metro)。如果你是Windows Phone用戶(hù)的話可能就會(huì)對(duì)Metro比較熟悉。事實(shí)上,微軟在2009年啟動(dòng)Windows 8的研發(fā)工作時(shí)目標(biāo)是創(chuàng)造一個(gè)完全不同以往的操作系統(tǒng),完全不以之前的操作系統(tǒng)為藍(lán)本。而后發(fā)現(xiàn)Desktop應(yīng)用是不可或缺的部分而將兩個(gè)部分進(jìn)行合并。一開(kāi)始用可能會(huì)有些別扭,但是我估計(jì)開(kāi)發(fā)人員半天之內(nèi)就能夠熟練使用這個(gè)系統(tǒng)了。
2.2 Metro和Desktop的一些不同
既然有兩種模式那么我們自然就會(huì)關(guān)注他們的不同點(diǎn)。這個(gè)問(wèn)題應(yīng)該從架構(gòu)圖上做一下說(shuō)明但是我們可以先有一些直觀的認(rèn)識(shí)。
2.2.1 Message Loop
消息處理的編程是傳統(tǒng)Desktop應(yīng)用程序的重要部分。你需要書(shū)寫(xiě)維護(hù)Message Loop的代碼。例如:在WinMain調(diào)用(或者其子例程中)你需要書(shū)寫(xiě)類(lèi)似
- while (::GetMessage(&message, NULL, 0, 0)) {
- ::TranslateMessage(&message);
- ::DispatchMessage(&message);
而在Window創(chuàng)建之前候你一定指定了
- WNDCLASS wndClass;
- // ...
- wndClass.lpfnWndProc = WndProc;
這樣你就可以在WndProc函數(shù)中決定特定message的流向了。對(duì)于繪圖來(lái)說(shuō),你一定是接受了WM_PAINT消息,然后執(zhí)行了區(qū)域重繪。
但在Metro App中這些都已經(jīng)隱藏了,而且消息的細(xì)節(jié)也可能發(fā)生了變化。Metro App中你看不到消息循環(huán)。一切關(guān)于界面消息的分發(fā)都隱藏在了CoreDispatcher中。因此如果你用Spy++去試探Metro App的消息循環(huán)那么你什么都抓不到。
2.2.2 Display
在傳統(tǒng)的Desktop應(yīng)用程序中,繪圖可能通過(guò)GDI,GDI+,DirectDraw,DirectX進(jìn)行。同樣通過(guò)捕獲WM_PAINT消息或者當(dāng)系統(tǒng)處于IDLE的時(shí)候進(jìn)行繪圖(對(duì)于游戲編程來(lái)說(shuō))。
而Metro App不會(huì)再支持GDI和GDI+,在Metro App中繪圖只能通過(guò)DirectX來(lái)進(jìn)行。確切的說(shuō)是Direct3D和新公布的Direct2D、Direct Write API。因此Metro應(yīng)用的所有繪圖都是希望是硬件加速的。這種繪圖更高效,解放CPU,而且一般不需要處理復(fù)雜的Dirty Region Repaint。
2.2.3 Life Cycle
Metro App并沒(méi)有關(guān)閉窗口這種按鈕。其生命周期是由系統(tǒng)托管的。系統(tǒng)會(huì)決定僅僅是掛起應(yīng)用執(zhí)行還是需要完全銷(xiāo)毀應(yīng)用進(jìn)程。這和一般意義上的Desktop應(yīng)用程序不一樣。(當(dāng)然,你也可以使用Alt+F4顯示的結(jié)束Metro App的執(zhí)行)。
2.2.4 Share & Communication
傳統(tǒng)的桌面應(yīng)用程序有多種手段進(jìn)行公共組建的公用或IPC。但是在Metro App中,隔離是一個(gè)很重要的概念,應(yīng)用的可執(zhí)行部分,運(yùn)行庫(kù),Isolated Storage都是獨(dú)立的,不能夠共用。同樣,不能夠使用傳統(tǒng)的IPC機(jī)制。應(yīng)用程序的互動(dòng)僅僅可以通過(guò)內(nèi)置的Contracts進(jìn)行,關(guān)于這一部分內(nèi)容可以查看MSDN:
http://msdn.microsoft.com/en-us/library/windows/apps/hh464906.aspx
2.2.5 Portability
傳統(tǒng)的Desktop應(yīng)用程序的支持大多為x86/64架構(gòu)的處理器。由于Metro環(huán)境可以完整運(yùn)行在ARM處理器上是一個(gè)重要的特性,因此Metro App可以運(yùn)行在ARM處理器上,即同時(shí)部署在PC和移動(dòng)設(shè)備上。
2.2.6 OS Access
當(dāng)然為了Portability的要求,必然要求應(yīng)用不能夠越過(guò)Win RT的抽象,因此Metro是不能像Desktop App那樣訪問(wèn)所有的Windows API的。
3 從Windows 8 API的架構(gòu)圖看Windows RT
我們對(duì)Windows RT的介紹都將圍繞著這個(gè)圖展開(kāi)。
在這個(gè)圖中,***層的是NT的內(nèi)核;在其上是Windows子系統(tǒng)。實(shí)際上NT至少有三個(gè)子系統(tǒng),Windows子系統(tǒng),POSIX子系統(tǒng)(Unix)和OS/2子系統(tǒng)。POSIX子系統(tǒng)和OS/2子系統(tǒng)實(shí)際還是在使用Windows子系統(tǒng)。 在Windows子系統(tǒng)上劃分了不同的運(yùn)行時(shí)(橙色)和程序庫(kù)(淺藍(lán)色),最上面的綠色是我們使用的各種開(kāi)發(fā)語(yǔ)言。
這個(gè)架構(gòu)圖實(shí)際上說(shuō)明了一切。并且消除了很多誤解:
(1)***個(gè)誤解是INFOQ指出的Windows RT和Win32是完全分開(kāi)的。這源于微軟發(fā)布的一幅飽受批評(píng)的架構(gòu)圖,在那張架構(gòu)圖中,Windows RT和Windows子系統(tǒng)竟然是并排排列的。這是很荒謬的,Windows RT實(shí)際上基于Windows子系統(tǒng)。首先Windows RT完全基于COM;其次Windows RT利用了一部分現(xiàn)有的Win32 API;其余的部分Windows RT則直接訪問(wèn)NT內(nèi)核。
(2)第二個(gè)誤解是C++/CX。C++/CX是微軟推薦的開(kāi)發(fā)Windows RT的方式。他主要隱藏了COM的復(fù)雜性。關(guān)于這個(gè)問(wèn)題我們后續(xù)會(huì)有說(shuō)明。這個(gè)誤解是C++/CX實(shí)際就是C++ CLI。實(shí)際上這是兩個(gè)完全不同的東西,C++ CLI是運(yùn)行在托管環(huán)境下的,而C++/CX完全是Native的。
3.1 Windows RT僅用于Metro應(yīng)用
從架構(gòu)圖中可以看出,Win RT僅僅用于Metro應(yīng)用。并秉承了我們剛才介紹的,簡(jiǎn)單部署,沒(méi)有共享的組件,沒(méi)有IPC,等等。
3.2 Windows RT構(gòu)建與COM之上
這也是為什么說(shuō)Windows RT是構(gòu)建與Win32之上,因?yàn)镃OM是Win32重要的組成部分。這意味著:
(1)你可以用之前所有的消費(fèi)COM的方式來(lái)使用Windows RT,你可以用C,你可以用ATL或者新的WRL;
(2)WRL完全符合傳統(tǒng)的C++語(yǔ)法,這意味著你可以使用不同的編譯器(例如Intel C++編譯器)來(lái)構(gòu)建Metro應(yīng)用。但是微軟顯然希望大家都來(lái)使用C++/CX,WRL的文檔跟沒(méi)有差不多,現(xiàn)在也看不到一個(gè)完整的例子出現(xiàn)。
3.3 Windows RT限制了系統(tǒng)API的調(diào)用
Win RT是基于COM的,但是COM僅僅是一個(gè)二進(jìn)制協(xié)議而已。在COM Interface實(shí)現(xiàn)中從技術(shù)上講還是在調(diào)用Win32 API。但由于前面介紹的Win RT的設(shè)計(jì)要求,系統(tǒng)API的調(diào)用需要受到嚴(yán)格的限制。僅僅支持有限的API調(diào)用,因此在你希望使用一個(gè)Win32 API時(shí),一定要查詢(xún)MSDN上的Applied To一節(jié),看看是否是Metro Style App | desktop App。
同樣的道理,.NET的某些方法也在進(jìn)行著系統(tǒng)調(diào)用,因此在使用.NET開(kāi)發(fā)Metro Style應(yīng)用程序的時(shí)候也并不是所有的程序集都能夠支持。當(dāng)然,如果使用P-Invoke的方式調(diào)用Win32 API那么危險(xiǎn)性就會(huì)更大。
總之,在Metro應(yīng)用中調(diào)用不支持的Win32 API會(huì)有如下的后果:
(1)發(fā)生一個(gè)Runtime Exception;
(2)應(yīng)用程序失去響應(yīng),尤其是在使用和消息循環(huán)相關(guān)的代碼時(shí)。例如對(duì)Metro App進(jìn)程使用WaitForSingleObject(hProcess)。
(3)調(diào)用成功,但是你的Metro App應(yīng)用會(huì)被Windows Store駁回。
按照上述分析,那么即使你存在相當(dāng)可觀的COM代碼庫(kù),也需要巨大的努力才能夠保證他們?cè)贛etro App上正確運(yùn)行(消除非法的系統(tǒng)調(diào)用)。對(duì)于新的應(yīng)用來(lái)說(shuō),為了避免書(shū)寫(xiě)大量的COM開(kāi)發(fā)代碼,***使用C++/CX進(jìn)行開(kāi)發(fā)了。
3.4 C++/CX
為什么會(huì)有C++/CX呢?這可以聯(lián)想n年前我們?yōu)榱吮苊釩++開(kāi)發(fā)COM的冗長(zhǎng)的代碼,轉(zhuǎn)而使用C開(kāi)發(fā)關(guān)鍵程序,而使用Visual Basic創(chuàng)建COM組件?,F(xiàn)在時(shí)間到了2012年,VB6已經(jīng)不在考慮范圍之內(nèi)了,于是C++/CX取代了他的位置。
C++/CX是Native的,但是它的語(yǔ)法為什么能夠和C++ CLI保持近乎一致呢?這是因?yàn)閃in RT本身雖然是Native的,但它以.NET兼容的方式暴露了元數(shù)據(jù)。但是我們?cè)诰幊讨幸獣r(shí)刻想到,我們?cè)诓僮鲗?shí)打?qū)嵉腘ative對(duì)象。根本沒(méi)有什么垃圾收集器在幫助我們。
那么為什么不單純使用.NET開(kāi)發(fā)Metro App呢?這是因?yàn)閷?duì)于移動(dòng)設(shè)備來(lái)說(shuō),CPU的速度和電池是兩大局限,因此在近一年,Go Native的大潮終于襲來(lái)。目前:
(1)iOS使用Objective-C進(jìn)行程序開(kāi)發(fā),而且在移動(dòng)設(shè)備上也是沒(méi)有垃圾收集器的,需要手動(dòng)釋放使用的內(nèi)存;
(2)Android一開(kāi)始使用Java進(jìn)行開(kāi)發(fā),但是在糟糕的性能和社區(qū)的強(qiáng)大壓力下,終于開(kāi)放了C/C++開(kāi)發(fā)接口;
(3)WP7/8也出現(xiàn)了類(lèi)似Android的情況。
目前客戶(hù)端應(yīng)用向更薄(核心應(yīng)用向服務(wù)器移動(dòng)),更快(運(yùn)行速度快,耗電?。换ジS富(沒(méi)有動(dòng)畫(huà)你都對(duì)不起觀眾)的方向發(fā)展。因此開(kāi)放Native接口是大勢(shì)所趨,C/C++順理成章的在Windows 8強(qiáng)勢(shì)回歸了。
但是,用.NET開(kāi)發(fā)Metro應(yīng)用也是一個(gè)不錯(cuò)的選擇,尤其你的應(yīng)用沒(méi)有密集的運(yùn)算(游戲)的情況下。你可以參考幻燈片中的Cheat Sheet。
原文鏈接:http://www.cnblogs.com/lxconan/archive/2012/09/09/2677957.html