如何收集分析数据而不破坏生产力

分析是现代移动应用程序不可或缺的一部分。 通过Analytics(分析),您可以收集有关用户的信息,以便开发和改进产品。

通常,收集信息会降低应用程序性能。 该过程还会加载CPU和内存,这是一个高昂的代价。 应用程序的慢速运行会导致负面的用户评论,降低评分并导致听众流失。

我们的Android开发人员小组在处理与新闻相关的下一个项目时遇到了这个问题。 我们必须在列表中注册每个新闻的显示。

尝试次数1


收到收集分析的任务后,团队迅速显示了结果。 生成事件的触发器是onViewAttachedToWindow方法。 一切似乎都很好,但是通过快速滚动,界面明显挂起-出了点问题。 这个问题必须解决。

每个人对暂停的看法都不一样,因此我们需要事实和证据。 为了测量延迟,选择了FPS(每秒帧数),并选择了FPS测量仪TinyDenser来测量延迟 。 连接实用程序后,团队获得了对该问题的客观确认-指示灯下降,有时非常明显:每秒少于30帧,打开该实用程序的屏幕录像如图1所示。

图片
图1.优化之前的屏幕录像

尝试次数2


如果您将发送事件推迟到用户滚动列表之前? 小组认为,嗯,决定创建事件队列,并在滚动停止后发送事件。 一切都很简单:我们将OnScrollListener添加到RecyclerView中,然后等待newState变为平坦SCROLL_STATE_IDLE-问题已部分解决。

class IdleStateScrollListener(private val analyticsFacade: AnalyticsFacade) : RecyclerView.OnScrollListener() { fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { analyticsFacade.setPending(newState != RecyclerView.SCROLL_STATE_IDLE) } } 

下一步是实现事件的累积及其分派。

为了管理队列,我们​​创建了一个类,负责将事件添加到队列并将分析发送到服务。 对于定期发送,我们选择了一个ScheduledExecutorService ,该线程具有一个每秒运行一次Runnable的线程,时间是根据经验选择的。

这立即产生了结果,FPS显着增加。 原则上,问题已解决,在图2中,我们在第二次尝试后看到了应用程序的结果。 但是只有一个任务-事件被发送到服务,这导致频繁生成Intent类的对象,这另外给GC造成了负担,并以“ 停下来的停顿”的形式交付了“令人愉快的事情”。

图片
图2.第二次尝试后的屏幕录像

尝试次数3


该团队认为:“一次发送一个事件,而不是发送事件列表是另一个好主意。” 在对该类进行了短暂的改进之后,该团队通过列表实现了事件的分配,并以每秒55-60帧的水平接收了稳定的指标值(图3)。

图片

图3.第三次尝试后的屏幕录像

结论


收集分析的琐碎任务变成了一个有趣且信息丰富的过程,在此过程中,团队利用其技能研究了应用程序性能问题并找到了解决问题的方法。 希望我们的经验对初学者和经验丰富的开发人员都有用。

还能做点什么吗?


我们的团队选择了第三个选项,但这并不是唯一可以应用的选项。

在当前实现中,当触发onViewAttachedToWindow方法时, 新闻将转换为分析事件对象,并因此创建一个新对象。 一种可能的解决方案是将转换延迟到发送之前:在队列中累积的不是事件,而是列表元素本身。 然后,当滚动处于SCROLL_STATE_IDLE模式时,将发生转换。 您还可以为事件创建对象池。 这些动作加在一起可以进一步提高应用程序性能。

Source: https://habr.com/ru/post/zh-CN414899/


All Articles