Android主线程收不到消息更新的问题分析
在工作中遇到一个问题,录制跟拍视频时,首次进入界面,点击开始录制时,视频播放和录制两个界面会同时开始播放。
接收播放器的回调,通过handler发送给主线程更新UI。
时间更新最小单位是0.1秒。
第一次进入界面,点击播放时,会等待1秒才开始更新进度,显示录制时间。
在同一个界面,删除当前录制内容,重新录制时,则不会等待1秒的时间。
在非UI线程的回调,以及UI线程的Handler消息中加入log,发现log有堆积现象,堆积的时间大约是1s。堆积之后,才开始
怀疑主线程被阻塞了,导致消息发不出来。
在回调函数和handler的消息处理方法中加入log,并带上线程ID,发现回调以及handler更新不在同一个线程中。
应该是主线程被阻塞了
如何查找原因呢?
想想是否可以用profiler的CPU工具(之前都没有这么用,但是感觉这里应该很有用,看callstack,看执行时间等等)
使用profiler,操作第一进入录制和录制之后删除再重新录制。
使用profiler的cpu 工具,点击start record 5s后点击stop record。
对比callstack的图, 发现横轴上 多了一段 长的蓝色线,移动鼠标发现是ThreadSleep 了1秒。觉得罪魁祸首应该是这里了!!!
顺着堆栈向上找,发现可以点击右键,进入代码。
发现是一个蓝牙的BroadcastReceiver的onReceiver接收消息里面有一个sleep(1000)的操作,感觉应该就是这里了。
因为BroadcastReceiver的消息是在主线程执行的,这里为了open 蓝牙sco,打开蓝牙接收设备,sleep了1s,所以这里1s正好阻塞了主线程的消息循环中的消息处理。
联系视频sdk部门的同事,去解决这个问题,不再放在UI线程中去sleep(1000)了
重新试验,问题解决。