写点什么

Activity 重启引起的重复发送消息 Bug 分析

用户头像
轻口味
关注
发布于: 刚刚
Activity重启引起的重复发送消息Bug分析

背景

IM 功能开发过程中,有这么一个需求,在打开会话详情页时 Intent 内可以携带一些消息,用于用户从商品详情页点击联系维护人时可以携带该商品的信息。Intent 内可以携带多条消息,用于跳转到会话详情页时自动发送消息。


后续做了一个提醒功能,客户发来消息,B 端用户端会弹出一个持续震动响铃的提醒页面,提醒页面有固定几条话术,点击后可以快速进入会话并自动发送该消息。

问题一:代码 Bug 引起的消息重复发送

有 B 端用户反馈,系统会自动发送消息,当时还觉得是服务端触发的,因为客户端不会触发自动发送消息逻辑,而且代码已经跑了很久没有修改,没有问题反馈了。但是排查消息发送源后发现确实是客户端发送的。通过日志定位客户端操作链路后发现是代码 Bug 引起。


  1. 用户在提醒页面点击快速回复,携带快捷回复消息进入会话后,会将该消息放置到成员变量的消息列表,开始初始化会话详情页,当拉取历史消息成功后,触发自动发送消息。此时还是正常的逻辑;

  2. 当用户点击了会话页面的“完善用户信息”消息跳转到完善用户信息页面,修改完对方信息后,会通过服务端触发一条更新会话信息的指令,而正是该指令又触发了重新拉取历史消息,而由于正常发送成功了没有清空消息历史成员变量,导致会再次触发发送该消息。


这里的问题主要是未清空初始化会话详情页时携带的消息内容引起。

问题二:Activity 重启引起的重复发送

解决完问题一有一段时间内没有上报该问题,但是这两天又有上报重复消息发送的触发,让人一头雾水。确认了用户已经使用了修复问题后的版本后,开始从日志排查。排查过程中发现,出现触发发送日志的地方有全局的进入后台,回到前台的日志打印,再发现有页面创建的日志,但是携带的参数还是第一次发送消息时的内容,猜测到可能是切入后台,页面被回收,重新打开系统又传递了第一次携带的内容,触发了 bug。


activity 的销毁分为正常销毁和非正常销毁:


  • 正常销毁:被销毁之后不会被自动重建。比如我们主动调用了 finish()、杀死了进程、用户通过点击返回键退出了 activity 等。它的生命周期:


onCreateonStartonResume
onPauseonStoponDestroy
复制代码


  • 非正常销毁:被销毁之后会被自动重建。比如,当系统内存紧张时,不可见的 activity 可能被销毁以节省内存,当 activity 被重新展现时就会被自动重建。当手机屏幕旋转时,activity(如果没有锁定方向的话)也会被销毁并自动重建。它的生命周期:


onPauseonSaveInstanceState*onStoponDestroy
onCreateonStartonRestoreInstanceState*onResume
复制代码


这里跟 onSaveInstanceState 没有关系了,非正常销毁时,系统再次传递了之前打开的 Intent 内容,导致触发了重新发送。

总结

遇到的问题都不是什么高深的技术,但是要排查还是有一定的难度,对开发过程的一些反思:


  1. 日志很重要,详细的日志信息可以大大节省定位问题时间;

  2. 一些链路较长,或者是不常触达的路径很可能隐藏 Bug,代码编写时要尽可能考虑到所有场景,测试 Case 的编写要尽可能完善。

用户头像

轻口味

关注

🏆2021年InfoQ写作平台-签约作者 🏆 2017.10.17 加入

Android音视频、AI相关领域从业者,开源RTMP播放器:https://github.com/qingkouwei/oarplayer

评论

发布
暂无评论
Activity重启引起的重复发送消息Bug分析