Windows 8 Metro開發疑難雜症(三)——導航(2),資料儲存,資料虛擬化

來源:互聯網
上載者:User

我在這個系列的第一篇就講到了導航的問題,不過可能有些問題還沒講明白,所以這裡再寫一篇關於導航的部落格。

這裡有兩個問題:

1.為什麼在調用Frame.Navigate方法的時候不能直接傳簡單類型以外的對象?

2.為什麼頁面每次back的時候都會初始化頁面?

我先來講下VS的項目模版,在我們建立項目的時候如果選的不是空白項目,VS自動會建立一個包含Common檔案夾的項目,而每個頁面都繼承自LayoutAwarePage,LayoutAwarePage幫我們做了很多必要的處理,看裡面的代碼你會發現LayoutAwarePage重寫了NavigateTo和NavigateFrom方法,而多了兩個LoadState和SaveState兩個虛方法。這樣我們幾乎可以忘了NavigateTo和NavigateFrom方法了,直接用LoadState和SaveState方法就行了。這裡還得說下為什麼LayoutAwarePage重寫了兩個方法,看LayoutAwarePage的代碼我們可以發現,LayoutAwarePage在NavigateTo方法裡面做了資料恢複的處理,當處理完了會調用LoadState方法,並把原來儲存的資料傳給LoadState方法,這裡的資料只有當back的時候才會有,因為只有在back的時候才會需要恢複資料。LayoutAwarePage在NavigateFrom方法裡面做了資料儲存的處理,當從當前頁導航到其他頁面的時候就會儲存你的資料,具體儲存什麼資料是需要你自己處理的。

然後我們再看下項目模版是如何幫我們恢複好儲存資料的.

我們所有經過SaveState方法儲存的資料都是SuspensionManager這個類來處理的,當程式啟動的時候,會在APP類的OnLaunched方法裡面會調用 SuspensionManager.RegisterFrame初始化SuspensionManager,如果程式是從掛起狀態恢複的那麼還會調用SuspensionManager.RestoreAsync方法來恢複資料。而當程式處於掛起狀態的時候,會在APP類的OnSuspending方法裡面調用SuspensionManager.SaveAsync來儲存資料(資料的儲存是以檔案形式儲存的)。

到這資料的恢複和儲存已經講完了,然後我要將下前面提到的第一個問題,為什麼在調用Frame.Navigate方法的時候不能直接傳簡單類型以外的對象?

問題就出在SuspensionManager.SaveAsync方法裡面,因為這個方法會調用Frame.GetNavigationState方法,這時候如果你頁面傳遞的參數是複雜物件,那麼直接crash,因為Frame.GetNavigationState無法序列化你的對象,就算你已經為你的類加上[DataContract]和[DataMenber]標記也沒用,對於這個問題我也問了微軟的相關技術人員,給我的回覆是在傳遞對象的時候把對象先序列化成字串,然後再在使用的時候還原序列化成對象,這不是坑爹的嗎!!!

 

下面講上面提及的第二個問題,為什麼頁面每次back的時候都會初始化頁面?

對於這個問題我是這麼認為的(純屬個人觀點,有臆測成分,歡迎拍磚)。

我覺得之所以每次back的時候頁面都會初始化,很大程度上是從記憶體的使用率來考慮的。我們從商店下載的APP,很大部分的APP都是以圖片來展示內容的,由於平板的螢幕肯定比手機大,那同時顯示的圖片數量勢必會比較多,就算你啟用了虛擬化技術還是會有這個問題的,一張圖片的體積差不多能頂得上一部小說了,而一個頁面同時顯示較多的圖片勢必會佔用較多的記憶體,而一個APP會有很多的頁面,如果每一個頁面都這樣的話那麼一個APP所佔用的記憶體將會有多大!現在當從當前頁導航到其他頁面的時候我認為系統會把原來頁面釋放掉以節約記憶體開銷,這樣你的APP配合資料虛擬化技術在記憶體的開銷上始終會處於一個穩定的狀態(我們目前開發的APP記憶體基本維持在60-80MB之間)。

另外我要說下什麼是資料虛擬化技術,資料的虛擬化是列表類控制項的專有的。假如你有1000條資料作為資料來源給清單控制項,如果你沒有啟用資料虛擬化(預設是開啟的),那麼清單控制項將會載入1000個item,每一個item都會佔用記憶體資源,可想而知你的app要佔用掉多少的資源,其實不只是記憶體的開銷,還有就是在你綁定資料來源的時候出現卡的現象(因為清單控制項要一下子初始化1000個item,不卡才怪!)。幸好目前的gridview,listview,listbox,flipview都預設啟用資料虛擬化的,這樣你有1000條資料的情況下,系統只要初始化10條或者更少的item(具體初始化多少條系統計算的),這樣一個減少了記憶體開銷,還一個是加快了清單控制項的初始化速度。

資料的虛擬化其實是依靠清單控制項的容器(ItemsPanel)來實現的,這些清單控制項預設的容器都是從VirtualizingPanel繼承過來的,在win8種WrapGrid和VirtualizingStackPanel都是支援資料虛擬化的容器。我們自己也是可以自訂支援虛擬化的容器的,不過這個過程是很複雜的。

目前我用了一款社交類的APP,我可以確定這個APP沒用啟用虛擬化技術,它有分頁功能,當我一直往下載入頁面的時候記憶體蹭蹭的往上漲,當我大概瀏覽到100頁的時候記憶體佔用已經有1G了,你沒看錯,是1G。

 

本篇到此!預告下下一篇

Window 8開發疑難雜症(四)——資料庫

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.