代码改变世界

Windows phone应用开发[17]-xap提交异常处理

2013-07-03 12:24  chenkai  阅读(1808)  评论(1编辑  收藏  举报

在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

无觅相关文章插件,快速提升流量