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)了
重新試驗,問題解決。