背景
公司有个app有聊天功能,但是最近测试小伙伴反馈,当项目群成员达到10000个时候,先进显示群成员列表,然后再返回的时候就会出现ANR
解决思路
第一步
使用adb获取anr报告
$ adb bugreport .
打开anr日记,搜索关键字 "main", 查到主线程的信息,这里我没有发现有用的信息
第二步
使用Android Studio cpu profile, 分析主线程上方法的调用情况,看是哪个方法执行耗时操作了
分析得到结果:当返回的时候在Activity的onResume方法中执行了从数据库查到数据的操作,后面分析数据库相关操作问题,原来在群成员列表界面直接了很耗时的数据库操作,虽然是在子线程里面跑的,但是打印了一下方法执行的时间差不多要5s,所有当主线程也要访问数据库的时候就造成ANR了
我们项目是使用ormlite来操作数据库,而且ormlite获取的数据库对象的时候会加一个同步锁,为了解决多线程访问的问题
解决
一开始在onResume方法中执行的数据库访问操作也放在子线程中,发现子线程执行完成后要回调通知主线程,这样代码逻辑改动很大,就放弃这个方案
后面想在群成员列表界面子线程执行耗时操作的时候加个判断,如果Activity已经退出的时候就退出循环,不向下执行,这就就可以数据库对象一直被子线程占用引用的这个ANR的问题
如果要完美解决的话,还是要把所有的数据库操作都放在子线程里面,而且当Acitivty退出的时候,Activity所使用的子线程来操作数据库的方法也要退出一下