Windows phone應用開發[17]-xap提交異常處理

chenkai發表於2013-07-03

在windows phone 應用提交操作上早在2011年時就寫過一篇Windows phone 應用開發[4]-應用釋出,那時wp應用提交官方市場的流程繁雜[超過了5步].因為上傳和填寫應用資訊頁面採用silverlight技術做的.載入速度有些慢再加上操作使用者體驗不好.導致很多開發者都在提交過程非常痛苦.在wp 7.8 更新發布後. ms官方也逐漸為了使提交應用更簡單.在應用提交流程上做了很大的簡化.其中最關鍵當屬完全去掉silverlight頁面.只在上傳xap包時保留了. 流程精簡為兩步[應用資訊和xap包提交]. 另外還增加每個步驟單獨儲存操作.這樣即使因為中間網路或是其他原因失敗.也可以儲存應用資訊 無需重複輸入.

而最近從朋友那拿到一個windows phone 開發者賬號.所以做了一個簡單的測試語音的應用.在提交時碰到從未碰到的異常.註明現在新版應用提交過程會驗證xap應用資訊. 如果存在驗證異常則無法提交應用 異常資訊超過45條如下:

2011: The background agent can’t use Microsoft.Phone.Shell.ShellTile::Create, which assembly TileAgent.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use Coding4Fun.Toolkit.Controls, which assemblyCoding4Fun.Toolkit.Controls.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use System.Windows.Controls.MediaElement::Stop, which assembly Microsoft.Phone.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use System.Windows.Controls.MediaElement::Play, which assembly Microsoft.Phone.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use System.Windows.Controls.MediaElement::set_Position, which assembly Microsoft.Phone.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use System.Windows.Controls.MediaElement::set_AutoPlay, which assembly Microsoft.Phone.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use System.Windows.Controls.MediaElement, which assembly Microsoft.Phone.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use System.Windows.Controls.MediaElement::SetSource, which assembly Microsoft.Phone.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use System.Windows.Media.VideoBrush, which assembly Microsoft.Phone.dll is trying to use. Update your file and then try again.

2011: The background agent can’t use System.Windows.Controls.MediaElement::.ctor, which assembly Microsoft.Phone.dll is trying to use. Update your file and then try again.

可以看到主要因為後臺任務background agent 中呼叫不收支援的API導致的.在windows phone 後臺任務ms官方規定所有可能涉及UI的操作api都是禁止呼叫的.官方在windows phone後臺代理概述中提到後臺任務中限制的api列表windows phone 後臺代理不支援的api.可見System.Windows.Controls名稱空間下MediaElement也是不支援的.而官方對這個錯誤表示程式碼2011 可以在瞭解應用提交錯誤中找到對應的說明:

2011

後臺代理無法使用程式集 [assembly name] 正嘗試使用的 [resource]。請更新檔案,然後重試。

知道大概原因再來看看具體的實際程式碼.首先看看解決方案專案結構.:

2013-07-03_105642

專案結構說明,VoiceControl使用啟動專案.設計UI. Common則用來封裝一些通用的操作或第三方可複用的類庫.TaskAgent就是後臺任務用來定時請求雲端語音識別資源然後更新控制播放並更新livetitle. 整個專案結構很簡單.專案間引用關係如下:

2013-07-03_111354

VoiceControl作為UI專案分別引用了Common類庫和後臺任務TaskAgent. 而後臺任務TaskAgent專案則引用Common類庫.既然異常提示說我們後臺任務TaskAgent專案使用限制的APi.後來我review分析後臺任務中操作的程式碼.後臺程式碼中根本沒有使用任何涉及UI操作的api.後臺任務其實就是做了兩件事:

A:請求雲端語音識別資料並更新Lock Screen識別出來的內容.

B:更新首屏live titles磁鐵

在來看看TaskAgent引用:

2013-07-03_113038

引用第三方分別Json.net序列化操作的. RestSharp則用來封裝windows phone 所有後臺資料請求. 都沒有涉及任何UI操作.所以這兩個第三方引用庫被排除.問題唯一可能出在及時Common類庫中.在來看看Common類庫的引用關係:

2013-07-03_113717

在Common中採用第三方類庫Coding4Fun中ToastPrompt控制元件實現類似Toast頂部通知提示效果.而這部分是涉及UI的操作的.放在Common類庫中目的是為了保證這部分程式碼隨著專案遷移可以複用.但我的後臺任務並沒有呼叫該程式碼.卻很奇怪的提示Coding4Fun.Tookit.Control嘗試去使用.這是為何?

見過一番測試發現.當在Common類庫中除掉Coding4Fun.Tookit.Control應用所有關於後臺引用異常提示都消失了.好吧換一種說法就明白了:

2013-07-03_114757

當Common類庫中引用涉及UI操作的第三方庫Coding4Fun.Toolkit.Controls.同時後臺任務引用Common類庫.即使後臺TaskAgent沒有呼叫Common涉及UI操作的程式碼.只要TaskAgent引用了Common類庫.如果Common類庫中包含涉及任何可能UI操作封裝的程式碼或是第三方可能會操作UI的引用關係. 那麼TaskAgent就會認為你可能會在後臺操作UI.導致提交程式碼時提示如上異常.這種做法的目的是從引用關係上就直接杜絕使用可能在後臺操作UI操作的可能.

知道具體的原因.ok.fix it up.

你突然發現很多Common類庫程式碼已經VoiceControl中被大量引用了.如果要刪除Common操作UI的程式碼.導致很多UI專案VoiceControl引用都需要手工替換.都快要上線了.這樣大幅的修改.難免會出現一些不可預測的Bug.好吧對於這樣手工活我向來都是抵制的.所以嘗試從引用關係上解決這個問題 .

在使用後臺專案中.我們在選擇封裝時.最好的選擇是把類庫和涉及UI的操作各自獨立成一個專案.而至於剛才多出引用替換. 我們可以不修改類和方法的命名.重新建立一個Components專案.把所有涉及UI操作的封裝都放到該專案.然後再VoiceControl UI 專案上只需要新增一個引用.而無需修改實際程式碼. 這樣減少可能出現Bug可能.這樣一來專案結構和引用關係又發生變化:

2013-07-03_120401

這時在提交Xap安裝包.所有涉及Coding4Fun和MediaElement異常就全部消失了.唯獨剩下一個:

2011: The background agent can’t use Microsoft.Phone.Shell.ShellTile::Create, which assembly TileAgent.dll is trying to use. Update your file and then try again.

well.可見在後臺任務TaskAgent建立磁貼的操作也是不允許的.其實同樣我的後臺任務只是負責更新磁貼而並未建立.原因還是一樣我們引用的Common類庫中設計磁貼Create操作.從而導致後臺任何可能try to use. 官方對於這點說明很明確:

ShellTile 類的 Update(ShellTileData) 方法

ShellTile 類的 Delete()()()() 方法

ShellTile 類的 ActiveTiles 屬性

這些方法可以用於修改正在執行的後臺代理中的 shell 磁貼。請注意,不能在後臺代理中建立[Create方法] shell 磁貼

找到Common類庫設計封裝live Title的類可見建立Title方法如下:

   1:      public void CreateFilpLiveTitle(string navigationUrl,string title,string backTitle,string backContent,string wideBackContent,
   2:             string smallBackgroundImage,string backgroundImage,string wideBackgroundImage, string backBackgroundImage, 
   3:             string wideBackBackgroundImage)
   4:          {
   5:              if (!CheckLiveTitleExistByUrl(navigationUrl))
   6:              {
   7:                  Uri titleUri = new Uri(navigationUrl, UriKind.RelativeOrAbsolute);
   8:                  ShellTileData titleData = CreateFilpTitleData(title, backTitle, backContent, wideBackContent, smallBackgroundImage, backgroundImage,
   9:                      wideBackgroundImage, backBackgroundImage, wideBackBackgroundImage);                
  10:                  ShellTile.Create(titleUri, titleData, true);
  11:              }
  12:          }

在一開始修改這個異常時,我把這部分程式碼註釋掉後用來測試.發現依然無法通過.xap包在上傳過程中會分析程式碼.同樣把這部分程式碼的操作放到Components專案中進行統一.然後再VoiceControl專案只需新增引用即可而無需修改實際的程式碼.

在上傳Xap安裝包發現驗證通過.沒有提示任何異常.

可見在涉及後臺任務的專案中.類庫和UI操作可複用封裝都需要各自獨立成單獨的專案. 而問題是所有這些提示後臺可能try to use 操作UI的API在實際開發和除錯過程都不會有任何提示.所以要保證後臺任務引用足夠的Clean並可複用.在發包上線時儘量不要手動修改實際程式碼.可以嘗試從引用關係解決關係依賴.程式碼就不貼了.

Contact me[@chenkaihome]

參考與引用:

windows phone background agent microsoft.phone.dll submission issue

why i got the background agent can’t use scheduledactionService::Add while sumitting my app?

Error 2011 the backgoud agent can’t use microsoft.phone.shell.applicationbarStateChangedEventArgs

相關文章