Activity 重启引起的重复发送消息 Bug 分析
背景
IM 功能开发过程中,有这么一个需求,在打开会话详情页时 Intent 内可以携带一些消息,用于用户从商品详情页点击联系维护人时可以携带该商品的信息。Intent 内可以携带多条消息,用于跳转到会话详情页时自动发送消息。
后续做了一个提醒功能,客户发来消息,B 端用户端会弹出一个持续震动响铃的提醒页面,提醒页面有固定几条话术,点击后可以快速进入会话并自动发送该消息。
问题一:代码 Bug 引起的消息重复发送
有 B 端用户反馈,系统会自动发送消息,当时还觉得是服务端触发的,因为客户端不会触发自动发送消息逻辑,而且代码已经跑了很久没有修改,没有问题反馈了。但是排查消息发送源后发现确实是客户端发送的。通过日志定位客户端操作链路后发现是代码 Bug 引起。
用户在提醒页面点击快速回复,携带快捷回复消息进入会话后,会将该消息放置到成员变量的消息列表,开始初始化会话详情页,当拉取历史消息成功后,触发自动发送消息。此时还是正常的逻辑;
当用户点击了会话页面的“完善用户信息”消息跳转到完善用户信息页面,修改完对方信息后,会通过服务端触发一条更新会话信息的指令,而正是该指令又触发了重新拉取历史消息,而由于正常发送成功了没有清空消息历史成员变量,导致会再次触发发送该消息。
这里的问题主要是未清空初始化会话详情页时携带的消息内容引起。
问题二:Activity 重启引起的重复发送
解决完问题一有一段时间内没有上报该问题,但是这两天又有上报重复消息发送的触发,让人一头雾水。确认了用户已经使用了修复问题后的版本后,开始从日志排查。排查过程中发现,出现触发发送日志的地方有全局的进入后台,回到前台的日志打印,再发现有页面创建的日志,但是携带的参数还是第一次发送消息时的内容,猜测到可能是切入后台,页面被回收,重新打开系统又传递了第一次携带的内容,触发了 bug。
activity 的销毁分为正常销毁和非正常销毁:
正常销毁:被销毁之后不会被自动重建。比如我们主动调用了 finish()、杀死了进程、用户通过点击返回键退出了 activity 等。它的生命周期:
非正常销毁:被销毁之后会被自动重建。比如,当系统内存紧张时,不可见的 activity 可能被销毁以节省内存,当 activity 被重新展现时就会被自动重建。当手机屏幕旋转时,activity(如果没有锁定方向的话)也会被销毁并自动重建。它的生命周期:
这里跟 onSaveInstanceState 没有关系了,非正常销毁时,系统再次传递了之前打开的 Intent 内容,导致触发了重新发送。
总结
遇到的问题都不是什么高深的技术,但是要排查还是有一定的难度,对开发过程的一些反思:
日志很重要,详细的日志信息可以大大节省定位问题时间;
一些链路较长,或者是不常触达的路径很可能隐藏 Bug,代码编写时要尽可能考虑到所有场景,测试 Case 的编写要尽可能完善。
评论