[原文發表地址] Updating my Windows Phone App to Windows Phone 8
[中文原文地址] 將我的 Windows Phone 應用程式更新到 Windows Phone 8
[原文發表時間] 2012-12-8 12:53
今年早些時候,我花了一天編寫了一個小的 Windows Phone 7 應用程式,我將它稱之為Lost Phone Screen。它能為你建立鎖屏,並在上面顯示你的姓名和聯絡號碼,以便當你丟失它時,用老辦法協助找到你的手機。無需 GPS,你只須告訴你的同伴有一個小小的獎賞,然後讓他們撥打到電話。現在你可以免費下載它,大家無需為任何軟體付費,除了為憤怒的小鳥支付 99 美分。但我不痛苦。;)不管怎麼說,它非常適用於 Windows Phone 7 和 Windows Phone 7.5 (Mango)。
最近我得到了一個Windows Phone 8 的諾基亞 Lumia 920,因為有了許多新的API和功能供我可以利用-其中很重要的一點是也可以以編程方式設定手機的鎖屏,使用者將不需要做任何事-我認為是時候來更新它了。
我鼓勵你查看在6 小時內從概念到代碼:推出我的首個 Windows Phone 應用程式博文作為提醒,應用程式可以做什麼以及我編寫Windows Phone 7.x 版本遇到的問題。
這裡是我不得不考慮將應用程式更新到Windows Phone 8的緣由。非常感謝我在諾基亞的朋友Justin Angel在 Skype 上和我一起集思廣益,並協助編寫非同步代碼和解決問題。他的有關Windows Phone 8的最新功能博文是非常有用的,特別是他的小巧的 MultiRes 協助器類。
更新應用程式
首先,很明顯,現有的 Windows Phone 7 應用程式可以在Windows Phone 8上正常運行,而無需任何更改。它在 Windows Phone 8 上運行就如同在 Windows Phone 7 的一樣。我想要更新它以此來使用新作業系統上的新功能。
將項目升級到 Windows Phone 8
升級是很簡單的,我開啟舊的項目,然後它提示我升級。我雙擊 WMAppManifest.xml,並確保重申一些基本設定,像我的應用程式的表徵圖大小和磁貼,以及確認我的應用程式將需要像照片訪問等功能。
我確保勾選Supported Resolutions,因為我知道我稍後需要用到它。
儲存兩個分支VS一個超級項目
我反覆地這樣做。這是一個升級後的作業系統,但 99%的代碼將被共用。然而,已經改變了很多東西,因此我決定在原始程式碼控制中製作一個分支,而不是製作一個單個的產生。老實說,這裡有可能沒有錯誤的答案,你可以使用你所習慣的任意東西。如果我喜歡的話,我可以使用CSProj 檔案,或者只是製作一個不同的Build Configuration(組建組態)(如 Debug8 和 Debug7等),但我明白我的原始程式碼控制運行得非常好,所以最終我各有一個phone70 和 phone80分支,我在它們之間切換。更有可能的是我將更新 phone80 分支,然後"往後移植"新功能,現在這運作正常,但是我知道,如果我想要的話,我總是可以製作單個產生。
不過,最終我知道我各需要一個Windows Phone 7.x和 Windows Phone 8的產生,但我可以將它們以相同的名稱提交到Store,Store會處理好的。如果你的Windows Phone 8 採用一個新的螢幕解析度,你會獲得正確的版本,正如你可以在下面的螢幕快照所看到的。我已經提交了兩個 XAP 檔案。
新的螢幕解析度
我在幾周前更新了我的應用程式,但我的首個不錯的bug 發生在當HTC Windows Phone 裝置運行在解析度 1280 x 720,而不是 1280 x 768上時。它說:我的 lockscreens 被裁剪了! Windows Phone 8 其實有三種螢幕解析度,正如Justin所指出的:
這些螢幕解析度是: WVGA (480 × 800 像素),也用在 Windows Phone 7 中;WXGA (768 x 1280 像素),基本上是WVGA的高清版本;和 720 P (720 x 1280 像素),它使用的是與WVGA 和 WXGA不同的長寬比。請注意這些不同的解析度,請確保在排版螢幕時使用相對的<Grid/>定位,並為不同的解析度使用不同的媒體資產。
三種螢幕解析度是其次的,更有趣的是 720 p 是不同的長寬比!原來我在My Code中做了很多假設,不是螢幕解析度。我將15:9假設為 800 x 480和 1280 x 768的長寬比,但 16:9 是 1280 x 720 !
我最初的反應是,糟糕,現在我不得不真正思考。
事實證明它其實更簡單。在我的所有應用程式的頁面中,有一個頁面我能夠刪除其中的XAML 代碼,以及寫入程式碼邊距和行定義。我其實正在具體化,不讓系統本身以最佳方式進行布局。
我刪除了所有我硬式編碼邊距,並使用 "*"RowDefinition來改變了我的網格,"這意味著"其他的空間"是像這樣的:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
...
</Grid>
首個RowDefinition 填充了內容的大小,第二隻是佔據了其餘部分。這讓我的頁面在每個解析度的螢幕上看起來都很不錯,並很容易測試,因為我可以只是改變模擬器下拉式清單來選擇不同的解析度:
然而,在這些新的解析度中,我改變了我原先單一的 SplashScreenImage.jpg來包括每一個用於命名為 SplashScreenImage.Screen-720p.jpgSplashScreenImage.Screen WVGA.jpg 和 SplashScreenImage.Screen-WXGA.jpg的這三個解析度。你會發現你至少一半的時間在做 (不論是蘋果、 Windows 還是 Android)行動裝置 App程式擷取 PNG和圖稿檔案糾正)。
我不得不 (選擇)在App上的一個地方寫入程式碼(我可以質疑 Application.Current.Host.Content.ScaleFactor.Application.Current.Host.Content.ActualHeight 和 Application.Current.Host.Content.ActualWidth 是正確的)。我有個很特別的自訂裁剪影像控制,需要特殊處理的 720p 案例,可能由於我在XAML上技能的缺乏。它告訴我只有最前衛的邊緣情況需要這樣做,通常這是像素完美鎖定螢幕的創作中,所以你的汗可能一點都不會白流。
新的鎖屏API
最後,我的應用程式可以更新鎖定屏,而無需使用者手動幹預。這是我的首要要求,大家都以為是我的錯,該功能並不存在。其實它已經被添加到Windows Phone 8中。
如果你的應用程式想要更改鎖屏,它必須得詢問一次,並獲得許可。它必須提供"當前鎖屏供應商"。如果以上條件符合,它就會請求存取權限,然後設定鎖屏。
if (!LockScreenManager.IsProvidedByCurrentApplication)
{
LockScreenRequestResult result = await LockScreenManager.RequestAccessAsync();
if (result == LockScreenRequestResult.Granted)
{
SetAsWallpaper(filename);
}
}
else
{
SetAsWallpaper(filename);
}
SetAsWallpaper 只是一個關於LockScreen.SetImageUri() 的幫手。
private void SetAsWallpaper(string filename)
{
string realPath = "ms-appdata:///local/" + filename;
Debug.WriteLine(realPath);
//Debug.WriteLine(ApplicationData.Current.LocalFolder.Path);
LockScreen.SetImageUri(new Uri(realPath, UriKind.Absolute));
}
這就是它。可愛而簡單。但是。
使用非同步 API時一個非常重要的提醒
在 Windows 8 和 Windows Phone 8 中(由於 Windows 8 magic dust是位於Windows Phone 8) ,一切都是關於非同步和非阻塞 API。之前我只是儲存了壁紙,除了等待你別無選擇。現在所有的底層 API都是非同步(非阻塞),作為開發人員,我們有await /async 關鍵字來使事情變得簡單,對吧?
當然,我的第二個可愛的 bug在當大家多次點儲存按鈕時出現了。因為一切都是無阻塞的,這將關閉許多儲存請求,然後最終它們將碰撞檔案系統,然後出現"訪問被拒絕"。
我想要保護訪問這種共用的資源,但我不想鎖定UI。Michael L Perry有一個對此很好的解決方案,可能會構建到他的Awaitable Critical Section協助器的Windows Phone SDK 中(至少它是存在的,除非我們漏掉它?)。此協助器讓我們在使用熟悉的using{} 塊的情況下,在哪裡使用非同步和等待,什麼時候使用 lock() {} 塊。
正如Michael所指出的,你不能這樣做,因為你不能在一個鎖中等待。
lock (this)
{
FileHandle file = await FileHandle.OpenAsync();
await file.WriteAsync(value);
file.Close();
}
但有了此協助器,你可以執行此操作:
using (var section = await _criticalSection.EnterAsync())
{
FileHandle file = await FileHandle.OpenAsync();
await file.WriteAsync(value);
file.Close();
}
我就是這樣做的。
分析
當你完成時,請確保你運行 Windows Phone Application Analysis工具查看你的應用程式的情況。它使用太多記憶體了嗎?使用完電池了嗎?它是在一秒內啟動的嗎?
這是令人神奇的東西。讓你不用為你的App費勁心血,甚至讓你不用配置你的App提交你的應用程式和提交兩個版本時需要記住的新東西
我在 Windows Phone 7 版本中修正了一些 bug、更改了該 XAP 版本號碼,作為一個小的升級提交了它。擁有Windows Phone 7.X 版的人將會得到提示來更新他們的應用程式。此版本中,正如你所記住的,不會自動更新鎖屏,因為它不能。
進入Phone Marketplace,並從儀表板中點擊Update App。在我的更新之前,Marketplace顯示的是 7.1版本的應用程式:
點擊Update selected,上傳我剛建立的面向XAP 的新Windows Phone 7.1。上傳後我,更改下拉式清單,並上傳 Windows Phone 8 XAP。我確保要上傳發布一個Release XAP 和"AnyCPU"版本這兩種情況。
我一直儲存 Windows Phone 8 的幾個版本好讓我自己清楚。這對於我來說是有意義的,它協助我記住什麼是"最新"的,即使它只在意新版本會比以前的版本更高。
請務必檢查你的所有文本、說明和表徵圖,以確保它們是正確的。
花時間編碼vs花時間編輯 PNG
上天作證,與編碼相比,我發誓我花了更多的時間玩弄和PNG。
事情是這樣的:手機應用程式開發完全是有關螢幕和表徵圖的。
有這麼多的解析度、資產和不同的方案供你的應用程式展示,所以值得在 PhotoShop 或者Paint.NET上花費一些時間。其實,我所有的工作都是在 Paint.NET中完成的。
因為有三種解析度,您需要注意你需要三套螢幕!幸運的是有內建到Emulator中的工具, Windows Phone 還支援(最終)通過按電源 + Windows 鍵在裝置中截屏。
從marketplace中提交可能不那麼明顯,但您需要單擊 WXGA 和 720 p ,然後為每個上傳單獨!否則您的潛在使用者不會看到你的應用程式在其裝置上的情況。很枯燥,但至關重要。
說真的,這成了資產管理活。以 Jpg 和 Png 檔案夾填充而告終,僅保留了一些合理的檔案命名規範。
你最終會有至少 24 張(3 x 8)加上三個啟動顯示畫面,幾個表徵圖尺寸,你還會想要在黑暗和明亮的主題上測試。
結論
最後,它將為你的使用者無縫地銜接。擁有Windows Phone 8 的人將從WP8 XAP 中擷取更新, Windows Phone 7.x的人將從WP7-built的 XAP 中擷取。這整件事花了約 3個小時,大部分時間都在處理螢幕。