當前位置:首頁 » 安卓系統 » android同步機制

android同步機制

發布時間: 2023-07-29 05:46:49

① Android-Handler同步屏障

消息機制的同步屏障,其實就是阻礙同步消息,只讓非同步消息通過。而開啟同步屏障的方法就是調用下面的方法:

源碼如下:

在這里可以看到,Message對象初始化的時候並沒有給target賦值,因此target==null的來源就找得到了。這樣就可以插入一條target==null的消息,這個消息就是一個同步屏障。
那麼開啟消息屏障後,所謂的非同步消息又是如何處理的呢?
消息的最終處理其實都是在消息輪詢器Looper#loop()中,而loop()循環中會調用MessageQueue#next()從消息隊列中進行取消息。

從上面的MessageQueue.next方法可以看出,當消息隊列開啟同步屏障的時候(即標識為msg.target==null),消息機制在處理消息的時候,會優先處理非同步消息。這樣,同步屏障就起到了一種過濾和優先順序的作用。

如果上圖所示,在消息隊列中有同步消息和非同步消息(黃色部分)以及一道牆(同步屏障--紅色部分)。有了同步屏障的存在,msg_2和msg_M這兩個非同步消息可以被優先處理,而後面的msg_3等同步消息則不會被處理。那麼這些同步消息什麼時候可以被處理呢?就需要先移除這個同步屏障,即調用MessageQueue#removeSyncBarrier()

同步屏障一般在日常開發中比較少用,而在系統源碼中就有使用。Android系統中的UI更新相關的消息即為非同步消息,需要優先處理。
16ms左右刷新UI,而是60hz的屏幕,即1s刷新60次。
在Android中什麼是非同步消息?即給:

比如,在View更新時,draw、requestLayout、invalidate等很多地方都調用了。ViewRootImpl#scheleTraversals()。

在這里,mChoreographer.postCallback最終會執行到了Choreographer#postCallbackDelayedInternal()

可以看到,這里就開啟了同步屏障,並且發送了非同步消息。由於UI相關的消息是優先順序最高的,這樣系統就會優先處理這些非同步消息。
最後,當然要移除同步屏障的時候,調用ViewRootImpl#unscheleTraversals

在ViewRootImpl中的doTraversal()方法中也會移除同步屏障,這里移除是因為requestLayout或者invalidate的時候,刷新之後,在doTraversal()中就會移除同步屏障,因為此時消息已經發送並且處理了。

② androidUI卡頓原理分析及Vsync信號機制

一、UI卡頓定義 

1、用戶角度:app操作界面刷新緩慢,響應不及時;界面滑動不夠流暢; 

2、系統角度:屏幕刷新幀率不穩定,掉幀嚴重,無法保證每秒60幀,導致屏幕畫面撕裂; 

二、UI卡頓常見原因分析以及處理方案 

1、過度繪制: 

原因:界面布局設計不合理或者過於復雜導致系統無法在16毫秒內完成渲染,view過度繪制導致CPU或者GPU負載過重,View頻繁觸發measure、layout操作,導致measure、layout累計耗時嚴重以及整個View錯誤的頻隱讓繁重新渲染; 

方案:優化界面布局,使界面布局視圖扁平化,去除不必要的背景顏色,減少透明色的使用; 

方案依據原理:盡量減少View在系統中measure、layout、draw的累計時間; 

2、UI線程的復雜運算 

原因:UI主線程運算耗時 

方案:減少UI線程中數據運算,使用子線程處理耗時任務 

3、頻繁GC 

原因:(1)、內存抖動;(2)、瞬間產生大量對象,消耗內存; 

方案:盡量避免在循環邏輯或者onDraw方法中頻繁創建新對象和使用局部變數; 

三、android Vsync機制 

1、什麼是Vsync ? 

Vsync 是Vertical Synchronization(垂直同步)的縮寫,是一種在PC上很早就廣泛使用的技術,可則慶以簡單的把它認為是一種定時中斷。而在Android 4.1(JB)中已經開始引入VSync機制,用來同步渲染,讓孫攜握AppUI和SurfaceFlinger可以按硬體產生的VSync節奏進行工作。 

2、Android屏幕刷新過程 

Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染,屏幕的刷新過程是每一行從左到右(行刷新,水平刷新,Horizontal Scanning),從上到下(屏幕刷新,垂直刷新,Vertical Scanning)。當整個屏幕刷新完畢,即一個垂直刷新周期完成,會有短暫的空白期,此時發出 VSync 信號。所以,VSync 中的 V 指的是垂直刷新中的垂直-Vertical。 

3、沒有使用Vsync的情況 

可見vsync信號沒有提醒CPU/GPU工作的情況下,在第一個16ms之內,一切正常。然而在第二個16ms之內,幾乎是在時間段的最後CPU才計算出了數據,交給了Graphics Driver,導致GPU也是在第二段的末尾時間才進行了繪制,整個動作延後到了第三段內。從而影響了下一個畫面的繪制。這時會出現Jank(閃爍,可以理解為卡頓或者停頓)。這時候CPU和GPU可能被其他操作佔用了,這就是卡頓出現的原因; 

4、使用Vsync同步 

CPU/GPU接收vsync信號,Vsync每16ms一次,那麼在每次發出Vsync命令時,CPU都會進行刷新的操作。也就是在每個16ms的第一時間,CPU就會響應Vsync的命令,來進行數據刷新的動作。CPU和GPU的刷新時間,和Display的FPS是一致的。因為只有到發出Vsync命令的時候,CPU和GPU才會進行刷新或顯示的動作。CPU/GPU接收vsync信號提前准備下一幀要顯示的內容,所以能夠及時准備好每一幀的數據,保證畫面的流暢; 

5、多級緩沖 

Android除了使用Vsync機制,還使用了多級緩沖的策略來優化屏幕顯示,如雙重緩沖(A + B),當Display buffer A 數據時,CPU/GPU就已經在buffer B 中處理下一幀要顯示的數據了。 

可是,當系統資源緊張性能降低時,導致GPU在處理某幀數據時太耗時,在Vsync信號到來時,buffer B的數據還沒准備好,此時不得不顯示buffer A的數據,這樣導致後面CPU/GPU沒有新的buffer准備數據,空白時間無事可做,後面Jank頻出

因此採用三級緩沖來解決系統對性能不穩定導致的卡頓

當出現上面所述情況後,新增一個buffer C 可以減少CPU和GPU在Vsync同步間的空白間隙,此時CPU/GPU能夠利用buffer C 繼續工作,後面buffer A 和 buffer B 依次處理下一幀數據。這樣僅是產生了一個Jank,可以忽略不計,以後的流程就順暢了。 

註:在多數正常情況下還是使用二級緩沖機制,三級緩沖只是在需要的時候才使用;

熱點內容
伺服器雲主機改成雲電腦 發布:2025-03-18 02:46:11 瀏覽:422
php環境的搭建 發布:2025-03-18 02:44:47 瀏覽:489
java實現文件上傳到ftp 發布:2025-03-18 02:43:25 瀏覽:401
編程出遊戲 發布:2025-03-18 02:43:15 瀏覽:178
使用公網ip搭建伺服器 發布:2025-03-18 02:34:23 瀏覽:215
android從程序員到架構師之路 發布:2025-03-18 02:32:52 瀏覽:298
高壓存儲罐 發布:2025-03-18 02:23:18 瀏覽:760
加密卡怎麼模擬 發布:2025-03-18 02:02:08 瀏覽:271
我的世界伺服器水桶搭建 發布:2025-03-18 02:01:21 瀏覽:334
微信存儲到sd卡 發布:2025-03-18 01:34:29 瀏覽:969