内容字号:默认大号超大号

段落设置:取消段首缩进段首缩进

字体设置:切换到微软雅黑切换到宋体

业界资讯软件之家
Win10之家WP之家
iPhone之家iPad之家
安卓之家数码之家
评测中心智能设备
精准搜索请尝试:精确搜索

IT之家学院:如何解决UWP应用易闪退的问题

2018-7-23 10:02:19来源:IT之家作者:云之幻责编:白猫评论:

UWP应用,全称或许可称Windows通用平台应用,是微软推出的新一代Windows应用开发模型。但是自推出以来,却饱受诟病,其中,易闪退是很多人对它的第一印象。今天,我们就来谈一谈UWP应用闪退的问题,并教你如何解决它。

本文所述是立于开发者角度,即从应用代码解决问题。而非处于用户角度,在应用之外解决UWP应用闪退的问题

大部分闪退的根源

UWP应用不是瓷娃娃,没那么易碎。“闪退”,归根结底其实是Windows对系统的保护,避免因应用而干扰到系统运行。这种处理方式是站在系统角度上的,但开发者和用户都不领情。

用户自不必说,应用闪退,极大地影响用户体验,闪退了几次就把软件卸载了,闪退的应用多了,连带着对整个UWP应用都讨厌上了。

而开发者也很纠结,用户抱怨出现闪退,可在开发者这里没办法复现,导致开发者调试困难,有时候也是不了了之。

那么大部分闪退的根源是什么呢?

一言以蔽之,就是出现了未捕获的异常,即UnhandledException

在写应用的时候,出现错误的原因多种多样,从大的架构设计失当,到小的出现了不安全的空(Null)值。这些错误,开发者有的可以在程序设计时就利用`try-catch`语句进行捕获,经验越丰富的程序员,设计时考虑到的可能异常就越多。但是人力有时穷,不可能方方面面都考虑到,而程序一旦在运行过程中出现了**未捕获的异常**,应用马上闪退,毫无二话。

照这样说,出现未捕获的异常似乎是在所难免的,可为什么有些应用基本不闪退呢?是它们的程序全身上下都是try-catch吗?

肯定不是啦~

解决未捕获的异常非常简单,即便算上大括号,也只需要5行代码就可以搞定。

如何一劳永逸地解决闪退问题

如上节所述,绝大部分闪退的根源是未捕获的异常。既然是未捕获,那我们把它捕获了不就完事了吗?

说起来简单,做起来……更简单!

每一个新建的UWP应用都有一个App.xaml的文件,其背后则有一个App.xaml.cs。

App.xaml.cs中包含着关于应用启动、暂停等应用层级的操作逻辑,这个我相信各位开发者都是知道的。而所有未捕获的异常,最终都会冒泡到这里,所以这里是最后一关。换句话说,我们只要在这里设一道卡,抓住这个异常,不让它触发闪退机制就万事大吉了。

App类派生自Application类,且自带了一个事件,就是UnhandledException,说明是**当异常可由应用程序代码处理,如从本机级别的Windows运行时错误转发时发生。应用程序可标记事件数据中处理的匹配项**。

换句话说,人家早就想到会有闪退这种情况,已经预先把这个事件给你定好了。那我们要做的就非常简单了。

首先,在App的构造函数里加上

this.UnhandledException += OnUnhandledException;

给这个事件绑定上一个处理函数。

接下来,我们就来写这个处理函数:

private void OnUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)

{

 e.Handled = true;

}

就这样,因出现未捕获的异常而造成的闪退就解决了,这个原因的闪退占了总体的九成以上。可以说,接下来,只要你的应用不作死,不故意写点死循环,不搞不安全的骚操作,基本上就不会再闪退了。

闪退问题的后续处理

出现闪退,意味着程序有错误未捕获。既然有错误,那就要解决。单靠一个e.Hanled=true;……

这种粗暴的解决方式虽然能够一次性解决闪退问题,但是治标不治本(虽然用户并不清楚,但实际使用体验却有了不少的提升)。作为软件的设计者,我们依然需要知道具体是哪里出现了问题,错误的原因是什么,这就涉及到了异常的后续处理。

如果你做的应用上架到了微软应用商店,那么在微软应用商店的后台,会记录你的软件在用户处的使用状况,而当出现异常的时候,也会上传到你的软件后台,这样就方便管理了:

你可以在后台观察出现的异常,然后在程序里解决它。

但是凡事总有例外,微软应用商店也不能捕获所有的异常并加以分析,这里分享一个例子:

我在开发WFA的时候,遇到过一个棘手的问题,Win10 14393的用户在打开应用设置时应用会闪退,而更高版本的则不会。当时在应用商店后台查看时,它也不知道原因,显示一个Unkonwn Exception,这我就很尴尬了啊。

百思不得其解的情况下,我在App.xaml.cs的异常捕获函数中加了个小东西,即捕获到异常后,将异常的解释传到我的数据库里。通过这样的方式,我很快找到了问题的成因,即AutoSuggestBox控件的某个样式在14393系统中不支持,这导致应用无法渲染,直接闪退了。

虽然最后我还是放弃了14393的支持(使用了ContentDialog的新控件),但这种本地处理也可以作为一个经验保留下来(现在的WFA也没有在异常捕获里加上传代码了)。

小小总结一下,闪退异常的后续处理可以通过两种方式来解决:

• 一种是依赖微软应用商店的异常上传机制,这种方式便于管理;

• 当前种处理方式不能满足需求时,可以在App.xaml.cs中的异常捕获函数里进行本地处理,将更为详细的信息上传到你的数据库中,便于你进行分析。

不过要注意,由于发布的安装包基本都是Release的,异常捕获不会有Debug时那样精准,有时候也需要自己根据情况进行分析。

第二种闪退原因

闪退原因可分为两部分,一种是我前面讲的代码中出现了未捕获的异常,而另一种,则是应用渲染无法获取到对应资源,这一点就尤其显示出UWP开发平台的不成熟性了。

这种原因说白了其实就是“样式引起的闪退”,这个在我前面分享的WFA的例子中也提及过。

开发过UWP应用的同学对于控件样式应该不陌生吧。这个是UI的关键部分。而控件样式的设计,低版本(15063及以下)可以使用Blend,而更高版本,Blend尚未支持,就需要自己创建控件样式的副本,手动对XAML代码进行修改(我现在已经更偏向于这一种处理方式了)。

不论是利用Blend还是手动改,都需要创建控件样式的副本,这个副本依据什么创建的呢?依据的是系统默认的样式。而系统默认的样式有一个很严重的问题,以16299为例。

众所周知,在16299中,Win10采用了Fluent Design,很多控件的默认样式都进行了更新,添加了一种名为AcrylicBrush的笔刷,而在最新的17134中,则有Reveal光效。当这些仅特定版本支持的特殊样式被内化到系统默认样式中,一件凄凉的事情就发生了:

一个最为基础的控件,你认为的各个版本都会支持的控件,却偏偏成了闪退的罪魁祸首。

原因就在于你使用高版本Win10进行开发时,控件的默认样式已经不再支持低版本了,而你却对此并不了解,导致你没修改控件的样式。这样的应用做出来,虽然名义上支持低版本,但是低版本打开后会因为应用找不到对应的系统资源而无法渲染,因此闪退。

因这种原因而闪退的应用也屡见不鲜,很多时候都是开发者没有经过认真比对而强行上新的效果造成的。

但是你说这个是开发者的原因吗?或许是,但微软也需要承担一定的责任。你控件更新就更新吧,好歹告诉我一声啊,就算没写什么更新说明,那么在创建默认样式时,加个波浪线,告诉一声“该样式在当前软件的最低系统版本中不受支持”也好啊。但很可惜的是,目前这种提示文字有,但不全面,仍有一些样式没有被包括在提醒列表之内。

所以,当你在App.xaml.cs中完成了对代码的异常捕获后,如果应用依然会出现闪退,那么你就要考虑一下这种样式原因了。

个人博客地址:blog.richasy.cn

相关文章

关键词:UWPUWP闪退

IT之家,软媒旗下科技门户网站 - 爱科技,爱这里。

Copyright (C)RuanMei.com, All Rights Reserved.

软媒公司版权所有