查看原文
其他

Android vitals 帮您解决应用质量问题 (下篇)

Google Play 谷歌开发者 2019-02-14

作者:Wojtek Kaliciński, Android 开发推广

很高兴看到越来越多的开发者利用 Google Play 管理中心内的 Android vitals 板块成功解决各类应用质量问题。自从第一篇 Android vitals 的文章发表以来,我们一直在不断改进 vitals,希望给开发者带来更多新指标与新特性。在这篇文章中,我会先简要介绍一下 vitals 中引入的新特性,然后针对唤醒锁卡住及应用崩溃这两个问题展开深度探讨。



Android vitals 新特性

Google I/O 2018 开发者大会期间,我们推出了一系列 Android vitals 新特性:在改善已有指标的同时,新增加了两项数据类型,此外还引入了通知功能,让开发者能够及时获知应用各项 vitals 指标数值的变化。


类别基准

应用在 Google Play 应用商店中所属的类别不同,对应的 vitals 指标的衡量基准也会不同,比如:与 “竞速类” 应用相比,“桌面和棋类” 应用的平均启动延迟更低。为此,Android vitals 加入了 “类别基准” 这一数据,让开发者可以了解与同类其它应用相比,自己的应用的性能表现处在何种水平上。 


异常检测

应用行为突然发生变化可不是什么好消息。为了帮助开发者迅速解决这个难题,Android vitals 一旦发现指标数值突然上升,就会立即在 Play Console 中显示警报,同时向您发送邮件,然后您就可以在页面内查看具体情况并采取应对措施。


权限遭拒
您可在 Android vitals 查看拒绝授予应用权限的用户的百分比。如果您的应用的权限遭拒次数过多,建议您改进应用设计,例如,使用更准确清楚的措辞来描述应用请求权限的理由,然后再观察情况是否得到缓解。


应用启动时间

即使应用在功能交付或游戏体验方面都具有出色表现,过长的启动时间依旧会导致用户的流失。因此,为了帮助开发者了解应用是否存在启动时间过长的问题,我们在 Android vitals 内新加入了 “应用启动时间” 这一数据类型,以显示应用在冷、温和热这三种系统状态下的启动速度:

  • 冷启动:应用近期未被使用,且当前未缓存在内存中;

  • 温启动:应用已缓存在内存中,但是需要重新创建活动;

  • 热启动:当用户通过系统导航重回应用时,后台已有该应用的进程,即应用和活动均缓存在内存中。


当 Android vitals 显示您的应用存在启动问题时,建议您使用 Android Studio 3.2 提供的全新 Android Profiler 分析工具,如应用启动 CPU 分析和 Systrace,调取相关数据,找出导致启动延迟的具体原因。


>> Android Studio 3.2 视频:

https://www.youtube.com/watch?v=Hzv5-R9XLTc



Android vitals 核心指标

想要打造出高质量的应用,开发者必须认真考量每一项 Android vital 指标,而其中的 4 项核心指标 —— 唤醒次数过多、应用程序无响应 (ANR)、后台唤醒锁卡住以及应用崩我在第一篇文章中已经讨论了过度唤醒和 ANR 这两个问题,接下来我们来一起谈谈唤醒锁和应用崩溃。


唤醒锁

过去,应用必须通过创建后台服务才能在 Android 系统中实现后台运行,而且在此过程中,还需要保证后台服务一直处于活动状态,因此后台服务又被称作 “自由运行服务”。应用在运行后台服务的时候,需要使用唤醒锁来防止 CPU 和基带处理器进入休眠状态。


但是这种使用唤醒锁的方法也有不足之处。频繁创建后台服务可能会让应用运行时间过久,导致内存一类的系统资源无法得到释放。CPU 和基带处理器的使用让设备无法进入休眠状态,进而严重影响设备的性能和续航能力。


应用可以通过 PowerManager 类获取部分唤醒锁 (partial wake locks),它能确保在设备关闭屏幕和键盘背光后,CPU 依旧可以正常运行。请您前往 Android vitals 中的 “唤醒锁卡住” 和 “唤醒锁卡住 (后台) ” 页面,查看应用中部分唤醒锁的使用报告。


在报告中,您能了解有多少比例的电池工作时段 (即设备两次满电之间的时段) 受到了唤醒锁卡住事件的影响。详细信息包括:

  • 在过去的 30 天内受影响工作时段的百分比;

  • 按基准比较的详细信息:即您的应用与 Google Play 中排名前 1000 应用的对比情况;

  • 受影响的工作时段在一段时间内的变化趋势图;

  • 按应用版本、Android 系统版本以及设备型号等维度细分后的指标值 (细分指标并非以截图形式呈现,开发者可以点击栏目右侧的向下箭头,即可展开相关详细信息)。

如果基准显示您的应用属于这项指标 (即受影响的工作时段) 的最低 25% 区间,请考虑对改进您的应用。


正如我在第一篇文章中提到的一样,自从 Android 5.0 引进 JobScheduler 以来,解决过度唤醒的最佳方法就是避免使用标准闹钟以及后台服务。从 Android Oreo 开始,此举变为强制性要求,应用无法再在后台启动服务 (如果创建则导致异常)。同样地,我们也建议开发者减少使用唤醒锁,转用其它更为合适的替代方法,如:

  • 请使用 JobScheduler 或者调用 WorkManager API 处理后台任务,它们在后台任务运行期间会一直持有一个唤醒锁;

  • 如果您想要每隔一段时间或者在特定时间在后台运行任务,您可以使用 Alarm Manager 发送广播。Alarm Manager 在 BroadcastReceiver.onReceive() 方法的执行期间会一直持有一个唤醒锁;

  • 请在窗口上添加 FLAG_KEEP_SCREEN_ON 标记,保持屏幕背光常亮,以防在用户观看屏幕时 (如阅读电子书),设备突然进入锁屏状态。通过这种方法方法,系统在活动结束后会立即释放唤醒锁。


如果您需要自行管理唤醒锁,比如长时间使用前台服务来播放音频,请遵循以下规则:

  • 请使用 PARTIAL_WAKE_LOCK,而非已弃用的唤醒锁;

  • 请明确规定唤醒锁有效时间,那么,即使应用没有释放唤醒锁,系统也会在有效时间到期后自动释放唤醒锁;

  • 请在唤醒锁上添加静态的描述型标签,如 com.myapp: my wake,以便在 Android vitals 上获取最佳报告数据。请不要添加 counters (计数) 或者其它动态标签。良好的描述型标签可以帮助 Android vitals 对应用中相似的唤醒锁进行合并 (cluster),从而让开发者能够更准确地了解每个唤醒锁的行为;

  • 当应用不再需要唤醒锁时,必须将其立即释放。不过,请注意应用程序错误也同样会导致唤醒失效,为避免此类情况发生,建议您进行防御性编程,并且使用 try { … } finally { wakeLock.release(); } 包装调用。


应用崩溃

您可在 Android vitals 上获取应用崩溃的概览信息以及详细分析。在崩溃率和多次崩溃率页面上,系统会结合使用崩溃数据和使用情况数据来创建标准化指标。

除了概览信息以外 (见上图),您还可以在 ANR 和崩溃次数页面查看应用崩溃的实时数据。


与后台唤醒锁卡住类似,不良行为阈值是判断应用崩溃率的指标关键指标:如果您的应用的崩溃率高于不良行为阈值,建议你优先解决应用崩溃问题。


代码产生异常或导致应用崩溃的原因有很多,本文无法 一一 涵盖,因此,下文仅列举了几条通用建议供开发者参考,希望能够帮助大家避免应用崩溃的问题。


通过 Android vitals 这条有效途径,开发者能够迅速了解常见崩溃的相关信息以及受影响用户的数量。Android vitals 的主要优势在于:它能在第三方崩溃报告 SDK 初始化之前就捕获崩溃异常。


如果您想进一步了解如何复现,排查和修复应用崩溃问题,建议您使用 Firebase Crashlytics 崩溃报告分析工具。该工具集成了 Firebase Analytics,并且允许用户在报告中添加自定义日志,从而帮助开发者实时了解应用崩溃的相关信息并获取富有实用价值的分析洞见。


>> Firebase Crashlytics

https://firebase.google.com/docs/crashlytics/


通过采用以下三条建议,开发者能够避免大部分常见代码错误,减少应用崩溃率:

  • 减少并消除样板代码;

  • 转用 Kotlin;

  • 使用公共 API



减少并消除样板代码

开发者没有必要自己动手编写常见任务的代码,主要有如下两点理由:首先,自行编写无法保证百分百正确;而且,市面上已经有许多现成的优质源代码库可供使用,它们提供的代码不容易导致程序崩溃而且方便重复使用。

Android Jetpack 就是其中一个很好的例子,它提供的支持库中包含了适用于大部分 Android 应用的通用基础架构代码,开发者可以把它们灵活运用到自己的代码中。您可以利用 Android Jetpack 管理各种常见任务,如生命周期管理、导航、运行后台任务、数据库操作、从外部源代码库下载数据等等。而且您也没有必要只局限于 Google 开发的库,市面上还有很多优质的成熟开源库可供您探索和使用。



从 Java 转用到 Kotlin

在去年的 I/O 开发者大会上,我们宣布 Kotlin 成为 Android 官方支持的编程语言。目前,我们正在积极投入相关资源,进一步加强对 Kotlin 的支持,帮助开发者规避常见代码错误,减少应用崩溃率,最终达到提高开发效率的目的。


Kotlin 的主要优势在于它在语言类型系统中内置了可空类型。开发者可以利用空安全调用 (null-safe calls) 和编译时空检查 (compile-time null checks),确保代码在运行时不会产生 NullPointerException 异常。如果您尚未使用过 Kotlin 进行开发,不妨着手一试。Kotlin 和 Java 有很强的互操作性,因此没有必要将应用中所有的 Java 都转换成 Kotlin,您可以按照自己的节奏在应用中添加 Kotlin 代码。


>> Kotlin 开发者官方文档链接:

https://developer.android.google.cn/kotlin/



使用 Android 公共 API

公共 Android API 是指在 Android 官方文档中有记录的类和公共方法。所有通过认证的 Android 设备都可以调用公共 API;而私有方法和隐藏方法只能通过反射来调用,而且很容易导致应用崩溃。私有 API 的主要风险有如下三点:

  1. 无法保证能被所有设备调用;

  2. 可能会发生变动;

  3. 在系统版本升级后,可能会失效。如果您只是私下调用私有 API 用于个人开发试验,问题不大,但是对于需要发布至 Google Play 应用商店中的公开应用,我们不推荐您调用这些 API。


由于私有方法和隐藏方法存在不少隐患,我们从 Android P 开发者预览版开始引入对私有 API 的访问限制,建议开发者立即停止调用这些 API 已确保应用兼容性。您可查阅《非 SDK 接口相关限制》,获取更多信息。


>>《非 SDK 接口相关限制》开发者官方文档链接:

https://developer.android.google.cn/preview/restrictions-non-sdk-interfaces



结语

Android vitals 致力于帮助您开发出更优质的应用,让更多用户体验精彩,创造真正的商业价值。这两篇文章中,我对 4 个 Android vital 关键指标 —— 唤醒次数过多、应用程序无响应 (ANR)、后台唤醒锁卡住以及应用崩溃,进行了详细论述,并且介绍了 Android vitals 最近加入的几项新特性。


希望各位开发者能够将本文提到的建议和想法实践到应用开发中,理解各项 Android vitals 指标对于应用的意义,并根据这些数据进一步提升应用性能。


如果您想要获取进一步信息,请收看 Google I/O 2018 开发者大会的相关分享 ——《Android vitals:解决应用性能问题,收获商业成功》(https://youtu.be/dx6LBaFqEHU)



 点击屏末 |  | "我们愿意更好地倾听您的声音 "




推荐阅读:

· Android vitals 帮您解决应用质量问题 (上篇)

· 和 Google Play 一起展望未来

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存