Android 丟幀原理以及辦法

接近年底,想分享點(diǎn)兒東西給大家水评。

Android UI繪制過程

開發(fā)中的卡頓我想沒跟人都遇到過猩系,之前也是搜博客看看怎么個解決辦法,沒有認(rèn)真研究過中燥,今天我打算跟大家聊一聊寇甸。

先從View 說吧。相信大家應(yīng)該都知道View的繪制過程疗涉,measure幽纷,layout,draw博敬。丟幀一定是在16ms內(nèi)沒有把這些事兒干完就對了友浸,這里我們簡單的分一下,主要是計(jì)算時間偏窝,以及繪圖時間收恢。

計(jì)算時間:這里的measure武学,layout的過程,都是會向下遞歸計(jì)算的伦意,學(xué)過數(shù)據(jù)結(jié)構(gòu)的話火窒,應(yīng)該知道,深搜的代價是很大的驮肉。所以盡量讓樹的高度降低熏矿,這里就引出扁平化布局。

繪圖時間:這里需要著重講一下离钝,因?yàn)橛袝r候這才是我們UI卡頓的主要原因票编。在這里我們要把a(bǔ)ndroid的試圖看成是三維的,就像photoshop的圖層一樣卵渴。android在繪制的時候就會一層一層的“粉刷”慧域,好了,那么造成卡頓浪读,也就是丟幀昔榴,說白了最后沒有在16ms內(nèi)做完。好了碘橘,讓我們剖析一下:

1.invalidate():

我們知道invalidate 是用來請求View 重繪的互订,

invalidateInternal

這里可以看出來draw的過程其實(shí)就是拿到AttachInfo 里面包含著繪制信息,以及將繪制區(qū)域拿到痘拆,通過parent去繪制屁奏。讓我們跟進(jìn)去蜈出。

invalidateChildInParent

這里的dirty代表你繪制的這塊區(qū)域是否透明当纱。

invalidate

這里我們看到了個關(guān)鍵函數(shù) scheduleTraversals 张症,為什么說神奇宴合。我們看一下


scheduleTraversals

這里最重要的是Choreographer 這個蝌箍,我們最終算出來的繪制信息都要通過它回調(diào)跋选,開始他會注冊一個廣播用來接收時鐘信息棍好,然后他會在內(nèi)部建立一個UI繪制隊(duì)列:CallbackQueue斤寂,我們在外部CallBack的時候识颊,會將我們的繪制信息作為CallbackRecord 然后會在接收到一個時鐘信號的時候進(jìn)行doFrame操作诚镰,并打印Traces信息,從而來繪制一幀祥款。


CallbackQueue and CallbackRecord
postCallbackDelayedInternal

可以看到這里我們把我們的繪制內(nèi)容扔到隊(duì)列里清笨,等待輪訓(xùn)。

FrameDisplayEventReceiver

接收時鐘脈沖信號的廣播刃跛,16ms一次抠艾,我們的目的就是在這個時鐘脈沖里搞定整個 view

2.Android 動畫

Animator,ScrollTo桨昙,offsetLeftAndRight检号,這里面我們先單列這幾項(xiàng)腌歉,都是同一個原理。這里我們可以大膽的猜想齐苛,一定是頻繁執(zhí)行我們的 Choreographer.CallBack 來繪制翘盖,因?yàn)橹灰?6ms內(nèi)繪制成功,那就是流暢的動畫凹蜂。下面我們驗(yàn)證一下

ScrollTo:

我們先看一下 View 中這個方法

scrollTo

很簡單馍驯,我們都可以看懂,開始位置玛痊,結(jié)束位置汰瘫,這里我們重點(diǎn)關(guān)注 postInvalidateOnAnimation() ?這個方法


postInvalidateOnAnimation

我們可以看到,這里的動畫過程繪制他還是扔到了ViewRootImpl 代理做這件事卿啡。

dispatchInvalidateOnAnimation

這里我們看到他開了個線程 mInvalidateOnAnimationRunnable 去添加我們這個將要繪制的 view吟吝,接下來我們繼續(xù)庖丁解牛


InvalidateOnAnimationRunnable

終于菱父,應(yīng)了我們的猜想颈娜,ViewRootImpl 有一個專門執(zhí)行動畫繪制操作的線程,我們可以看到 run() 里面不斷地CallBack浙宜,然后回收官辽,當(dāng)然里面有些線程鎖啥的不涉及本文就不細(xì)說了。

3.ValueAnimator:

這里我們有個 AnimationHandler 來執(zhí)行動畫操作粟瞬,這其中我們可以看到

doAnimationFrame

這里在不斷循環(huán)我們所有的anim同仆,并在不斷執(zhí)行 scheduleAnimation 方法

scheduleAnimation

剩下的大家自己翻閱源碼把。

這里總結(jié)一下裙品。我們所有界面上視圖的變化都是都是 ViewRootImpl 把需要重繪的東西填充 Choreographer 中的 mCallbackQueues 隊(duì)列俗批,然后在時鐘脈沖的廣播下進(jìn)行輪訓(xùn)執(zhí)行。

既然提到隊(duì)列市怎,假如我們在16ms內(nèi)大量的填充 AttachInfo 之類的繪制OBJ岁忘,就會導(dǎo)致無法再一次時鐘脈沖內(nèi)繪制完畢,就會在造成丟幀区匠,UI阻塞干像。

避免 Android UI 卡頓解決辦法

解決辦法:分析了好多,這里說兩個方法驰弄。

1.避免重繪麻汰,這里避免圖層(View)迭代。這里我們可以去開發(fā)者模式中對“顯示GPU視圖更新”打鉤


過度繪制


優(yōu)化以后

這里引用 http://hukai.me/android-performance-render 這篇博客的作者戚篙,盜個圖五鲫。??

這里可以進(jìn)行,選擇制定畫布繪制岔擂,而不是整個view去繪制臣镣「ㄔ福可以在onDraw中進(jìn)行限制,去限制繪制區(qū)域忆某,例如

canvas.clipRect(100,100,350,600, Region.Op.INTERSECT);

2.扁平化布局点待,歸根結(jié)底也是減少 mCallbackQueues 隊(duì)列大小。保證盡量在16ms內(nèi)繪制完畢弃舒,再有就是可以減少視圖 ViewTree 的高度癞埠,減少時間復(fù)雜度,從而優(yōu)化計(jì)算過程


xml代碼


優(yōu)化后的xml代碼

*附:


繪制層級

通過打開剛才說的開發(fā)者選項(xiàng)聋呢,來根據(jù)顏色來判斷頁面繪制情況苗踪。

距離回家還有8 個小時,17年希望可以發(fā)覺更多的東西給大家削锰,并且希望大家可以積極執(zhí)政文章中的錯誤通铲。祝大家新年快樂!??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末器贩,一起剝皮案震驚了整個濱河市颅夺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛹稍,老刑警劉巖吧黄,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唆姐,居然都是意外死亡拗慨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門奉芦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赵抢,“玉大人,你說我怎么就攤上這事声功》橙矗” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵减噪,是天一觀的道長短绸。 經(jīng)常有香客問我,道長筹裕,這世上最難降的妖魔是什么醋闭? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮朝卒,結(jié)果婚禮上证逻,老公的妹妹穿的比我還像新娘。我一直安慰自己抗斤,他們只是感情好囚企,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布丈咐。 她就那樣靜靜地躺著,像睡著了一般龙宏。 火紅的嫁衣襯著肌膚如雪棵逊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天银酗,我揣著相機(jī)與錄音辆影,去河邊找鬼。 笑死黍特,一個胖子當(dāng)著我的面吹牛蛙讥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灭衷,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼次慢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了翔曲?” 一聲冷哼從身側(cè)響起迫像,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎部默,沒想到半個月后侵蒙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體造虎,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡傅蹂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了算凿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片份蝴。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖氓轰,靈堂內(nèi)的尸體忽然破棺而出婚夫,到底是詐尸還是另有隱情,我是刑警寧澤署鸡,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布案糙,位于F島的核電站,受9級特大地震影響靴庆,放射性物質(zhì)發(fā)生泄漏时捌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一炉抒、第九天 我趴在偏房一處隱蔽的房頂上張望奢讨。 院中可真熱鬧,春花似錦焰薄、人聲如沸拿诸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亩码。三九已至季率,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間描沟,已是汗流浹背蚀同。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留啊掏,地道東北人蠢络。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像迟蜜,于是被迫代替她去往敵國和親刹孔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容