App应用性能监控实例分享U-APM:崩溃ANR双管齐下
Posted chen.yu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了App应用性能监控实例分享U-APM:崩溃ANR双管齐下相关的知识,希望对你有一定的参考价值。
一、App应用整体崩溃现状
应用性能稳定是良好用户体验中非常关键的一环,而现实情况却是应用崩溃、卡顿、加载缓慢、页面白屏等问题,频频出现在用户的真实体验之中,成为影响业务表现的直接杀手。据友盟新出炉的《移动应用性能体验报告》显示,App整体崩溃率为 0.293%,其中 android 端崩溃率为0.32%,ios 端崩溃率为0.1%。移动应用崩溃率随日活(DAU)规模增大而逐步下降。
常见的Android系统中,高版本崩溃表现显著优于整体均值。安卓版本的市场占有率以 Android10居首(32.03%), Android 8 (17.47%)略超出 Android9 (16.64%)这三个版本整体占据了2/3的 Android 市场,且崩溃率均在0.17%之下。
Android 市场中,品牌众多、机型分散,本报告主要展示市 占率较高的 Android 品牌崩溃情况。 热门品牌移动应用崩溃率表现良好: 整体来看,这些热门品牌的崩溃率控制较好。其中OPPO 、华为、 VIVO 是目前安卓手机崩溃率最低的三个品牌,均控制在 0.15% 之下。 大部分热门品牌的崩溃率也都低于安卓市场整体崩溃率 (0.32%),那么开发者在处理崩溃问题的过程中,不仅要关 注热门的品牌机型,还需要关注市场中各类小品牌的机型。
二、App奔溃捕获、减少ANR保持稳定的重要性
给App稳定性造成严重影响首当其冲肯定是奔溃或者ANR,如我们目前做的较多的都是浏览器App,App的稳定性则显得至关重要,如果奔溃率高了就会在谷歌市场评分变低,在Google Play上搜索"浏览器"关键字,App就不会出现在Google Play的前面,会导致曝光率下降,从而导致新增用户减少,新增用户少了,app获利就减少,,同理ANR的次数太多就会导致页面很卡,用起来不丝滑,用户体验就会非常不好,从而导致用户的留存率变得很低,留存率低了,App获利也会减少。一系列的bad circle就会循环往复。
在互联网存量时代,个体用户的体验提升变得越来越重要,因此应用性能管理(APM)受到开发者更多关注。据友盟的《移动应用性能体验报告》显示,截至2021年2月,应用商店上架应用集成三方 SDK 的比例 42.2%,且持续保持增长趋势。不同于其他开发者工具,应用性能管理SDK具有较强排他性,92%的应用仅会选择一款应用性能管理产品。
如我们自己使用的友盟应用性能监控U-APM,两行代码直接接入SDK,通过线上崩溃分析和监控,让App稳定性得到了大大提升,降低了崩溃率,解决了大部分特殊场景的ANR。
三、友盟U-APM在项目解决常见问题的场景分析
1、Exception奔溃场景分析
1)、NullPointerException奔溃场景分析
比如在我们浏览器app的下载模块,我们需要对下载好的文件通过后缀名进行简单的文件类型进行判断,然后我们获取文件后缀名的部分代码如下。
public String getLocalFileSuffix(File file) {
String path = file.getAbsolutePath();
String values[] = path.split(".");
return values[values.length - 1];
}
程序代码看起来没问题,后面在客户真实环境某种场景下,就奔溃了,然后由于我们集成了 "友盟U-APM"我们第一时间是到友盟后台进行日志查看,看是什么原因奔溃。
很明显,这里空指针导致奔溃了,我们可以看到是调用这个getAbsolutePath()函数导致,我们自然而然就会想到是我们file传递进去没有做null校验,导致程序奔溃,有了"友盟U-APM"我们第一时间把问题修复。
比如有时候浏览器需要点击来触发对比字符串是否相等,我们关键代码如下,在客户真实环境某种场景下,就奔溃了。
private boolean isSameFile() {
String filePath = file.getAbsolutePath();
if (path.equals(filePath)) {
return true;
} else {
return false;
}
}
我们到友盟后台进行日志查看,很明显这里是由于调用equals()函数空对象调用导致程序奔溃,有了"友盟U-APM"非常快速的帮我们定位问题。
2)、IndexOutOfBoundsException奔溃场景分析
比如在我们浏览器app里面会有文件名列表页面,我们会获取文件名相关函数操作,但是有时候开发会在文件名集合里面获取通过下标获取文件名,部分代码如下。
public String getFileName(int position) {
if (filenames != null && filenames.size() > 0) {
return filenames.get(position);
}
return "";
}
然后在客户现场也不是必线奔溃,偶然会发生,然后我们可以到"友盟U-APM"后台查看相关的信息。
很明显在getFileName函数里面出现了下标越界的异常导致程序奔溃,有了"友盟U-APM"可以非常轻松的定位奔溃问题。
2、ANR场景分析
主线程卡顿2秒,我们可以认为是ANR场景,这样我们的页面会卡住,有时候卡久了app就奔溃了,我们一般在主线程里面不进行网络请求操作,因为网络请求会耗时,非常容易产生ANR现象,然后我们浏览器项目里面部分页面加了清理功能,所以需要动态扫描某个文件夹,关键代码如下。
public void onClick(View v) {
try {
//获取path目录下的所有文件
ArrayList<File> allFiles = getLocalFiles(path);
//后面会对获取文件夹里面的allFiles文件进行处理
} catch (Exception e) {
e.printStackTrace();
}
}
这个代码因为我们当时用的是测试机,测试机path目录下文件非常少,我们在主线程运行没事,然后测试人员用测试机进行测试,也没有发现什么问题,后面到了真实环境由于在某个场景客户这个文件夹下面的文件非常多,然后就出现了ANR,我们到"友盟U-APM"后台看下数据,我们可以通过ANR分析看到多少用户ANR了,然后还有ANR的时间,对我们分析app的ANR起到关键作用,因为在我们测试环境,有些ANR不容易复现出来,而且就算复现了,我们一般不知道是在哪里发生了ANR。
接下来我们就去找ANR的具体位置在哪里。
客户环境这个getLocalFiles函数是递归函数,非常耗时,卡在了主线程。这里可以很清楚的定位到是哪个类的哪个函数触发了ANR,这里很明显是在onclick函数触发了,然后我们更具具体的类找到位置,第一时间修复,给客户解决了ANR问题,降低了app奔溃率,有了"友盟U-APM"妈妈再也不担心app发了ANR了和在哪里发生了ANR。
3、灵活的自定义异常场景分析
1)、直接把Exception抛给"友盟U-APM"后台
比如在我们浏览器app里面有非常多的url处理,我们有时候会需要对url获取host或者port来进行一些相关的处理,比如下面是app获取ur里面的port函数如下。
public int getPort(String url) {
if (TextUtils.isEmpty(url)) {
return 0;
}
try {
Log.d(TAG, "getPort start");
return new URL(url).getPort();
} catch (Exception e) {
e.printStackTrace();
MobclickAgent.reportError(MainActivity.this, e);
}
return 0;
}
但是在一些不合法的情况下,url的端口不合法,然后进入这个函数,我们直接会把exception抛给"友盟U-APM"后台,我们可以可以看下后台具体日志相关截图。
我们可以非常直观的看到是在getPort函数里面出现了MalformedURLException异常,然后不合法的端口是htto,不是一个合法范围的整数,有没有非常直观?,如果我不想把关键日志保存到手机本地,我们可以直接往"友盟U-APM"后台抛。
2)、把自定义的相关信息抛给"友盟U-APM"后台
比如我们浏览器app里面有判断当前网络是否连接vpn的函数代码,我们在发生异常部分直接自定义了一个“isconnectVpn”的"NetException"给了"友盟U-APM"后台。
public boolean isConnectVpn() {
try {
ArrayList<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
if (all == null || all.size() == 0)
return false;
for (int i = 0; i < all.size(); ++i) {
String name = all.get(i).getName();
if ("tun0" == name || "ppp0" == name) {
return true;
}
}
return false;
} catch (Exception e) {
e.printStackTrace();
UMCrash.generateCustomLog("isConnectVpn", "NetException");
return false;
}
}
打开"友盟U-APM"后台,相关日志信息如下,我们可以非常直观的看到我们上传的错误信息日志,可以帮助我们更好的分析问题。
四、友盟U-APM给我们产品带来的价值
1、可以帮助我们捕获浏览器app的所有奔溃,然后根据具体奔溃日志定位问题,提高了我们app的稳定性,从而提高了我们新增自然用户量。
2、可以帮助我们捕获浏览器的ANR行为,然后通过APM后台ANR的具体日志改善app,让我们的app更加丝滑,用起来非常爽、新增用户和用户留存率得到了大大提高。
3、人性化的自定义日志让app开发的时候人性化的抛相关信息给APM后台,让特殊场景我们得到妥善的处理,挖掘了用户很多珍贵的行为信息,为app的后续发展提供了不少帮助。
4、APM后台都是可视化,里面记录了app稳定性、对用户的行为和异常和具体日志有了各种记录和分析,可以帮助app整体分析和挖掘用户的潜在价值。
5、使用云真机,帮助让app质量验收到问题复现排查。
五、APM各产品平台的对比
1、U-APM和Bugly的对比优势
1)、U-APM支持错误详情的行为日志,但是Bugly不支持。
2)、U-APM支持用户行为、监控警告,云真机的测试能力、智能诊断、行为分析,但是Bugly不支持。
3)、U-APM支持启动分析、卡顿分析、页面监控、网络分析、内存优化等功能,但是Bugly不支持。
4)、U-APM一直都开发和维护,但是Bugly不在维护了。
2、U-APM和APMInsight的对比优势
1)、U-APM支持用户行为、监控警告,云真机的测试能力、智能诊断、行为分析,但是APMInsight不支持。
2)、U-APM支持错误分布,但是APMInsight不支持。
3、U-APM和Firebase Crashlytics的对比优势
1)、U-APM支持应用无响应 (ANR) 数据,但是Firebase Crashlytics不支持。
2)、U-APM支持用户行为、监控警告,云真机的测试能力、智能诊断、行为分析,但是Firebase Crashlytics不支持。
3)、U-APM支持启动分析、卡顿分析、页面监控、网络分析、内存优化等功能,但是Firebase Crashlytics不支持。
4、U-APM和 Android Vitals的对比优势
1)、U-APM支持奔溃分析,但是 Android Vitals不支持。
2)、U-APM支持用户行为、监控警告,云真机的测试能力、智能诊断、行为分析,但是 Android Vitals不支持。
3)、U-APM支持启动分析、卡顿分析、页面监控、网络分析、内存优化等功能,但是 Android Vitals不支持。
5、U-APM集成简单、拥有核心技术、服务有保障,"如友盟+发布的移动应用性能体验报告中就提到了U-APM提供长期稳定的产品迭代和项目服务及专家咨询能力、2行代码集成SDK、阿里巴巴核心团队联合友盟+ 多年技术沉淀为客户提供稳定可靠的性能监控与测试服务、秒级响应的项目服务群实时帮助您解答问题技术支持接入,SDK 隐私合规问题协助排查、行业数据白皮书、疑难问题技术专家咨询服务、定期举办线下活动&技术沙龙"。
Android Vitals、Firebase Crashlytics图片对比信息如下。
六、总结
友盟U-APM两行代码接入,在奔溃捕获、奔溃分析、错误分布、错误详情、细查结果、用户行为、监控警告,云真机的测试能力、智能诊断、行为分析、启动分析、卡顿分析、页面监控、网络分析、内存优化做的非常强大、对比竞品来说有明显优势,强烈推荐Android开发人员使用友盟U-APM,深入了解应用的性能和稳定性,集成简单、服务有保障,帮助您高效提升应用质量,让你的app变得如此丝滑。
以上是关于App应用性能监控实例分享U-APM:崩溃ANR双管齐下的主要内容,如果未能解决你的问题,请参考以下文章
Android性能优化之疑难杂症解决方案,U-APM的性能监控分析
Android性能优化之疑难杂症解决方案,U-APM的性能监控分析
Android性能优化之疑难杂症解决方案,U-APM的性能监控分析