Android中app卡顿原因分析示例
http://www.cnblogs.com/zhucai/p/weibo-graphics-performance-analyse.html
朱才
專注于Android圖形動(dòng)畫 MIUI工程師
隨筆- 21?文章- 0?評(píng)論- 164?Android中app卡頓原因分析示例
在知乎回答了一個(gè)“為什么微博的app在iPhone比Android上流暢”的問題。后面部分是一個(gè)典型的動(dòng)畫卡頓的性能分析過程,因此帖在這里。有編程問題可以在這里交流。知乎鏈接。
=========================================================
我來說下我所知道的事情。我不知道iOS為什么流暢,但我知道一些Android為什么不流暢的原因。
首先,就題主所說的問題,我用iPad和小米Pad對(duì)比了一下微博滑動(dòng)滾屏這件事情(2014年8月10日目前微博app最新版本)。正如題主所說,直觀感受上明顯感覺iOS要流暢、舒服。
在這件事情上我認(rèn)為主要是這三個(gè)原因:
當(dāng)你滑動(dòng)界面然后松手,這時(shí)界面會(huì)繼續(xù)滑動(dòng),然后速度減小,直到速度為0時(shí)停止。iOS下速度減小的這個(gè)過程比較慢,尤其是快要停的時(shí)候是慢慢停的,視覺上有種很順滑的感覺;Android下則從松手到停要快很多,相比之下有種戛然而止的感覺。
從數(shù)據(jù)/技術(shù)角度來看這個(gè)事情,我們滑動(dòng)界面的最終目的不是為了“動(dòng)”,而是為了“停”,因此只要平滑的到達(dá)目的地,似乎越快完成這個(gè)過程越好,所以Android的選擇是理所當(dāng)然的。但事實(shí)是,大家普遍更喜歡iOS的方式,這樣做顯得更順滑、更優(yōu)雅。
絕大部分時(shí)間兩者都能保持60FPS左右的滿幀率。但都會(huì)有偶爾的掉幀。并且Android上要比iOS上嚴(yán)重很多。(好吧,比起前兩年,已經(jīng)好太多了。)我前前后后滑動(dòng)了幾十次,iOS在前面遇到1次掉幀,后面就很穩(wěn)定了。而Android幾乎每滑動(dòng)一次都會(huì)伴隨一次掉幀。這完全就是真真實(shí)實(shí)的卡頓,用戶必然會(huì)感覺到那一刻的不流暢。Android掉幀的原因我后面再詳細(xì)分析。
從手指碰到觸摸屏,到屏幕上顯示處理這次觸摸產(chǎn)生的畫面,是需要時(shí)間的。時(shí)間越短感覺越跟手。據(jù)說iOS的觸摸屏的處理時(shí)間要比一般的Android手機(jī)快,這不是我的專長(zhǎng),不知道怎么驗(yàn)證。但在軟件系統(tǒng)層面,Android的顯示機(jī)制是app-->SurfaceFlinger-->Display,這比傳統(tǒng)的app-->Display多了一步,主要基于這個(gè)原因,畫面最終輸出到屏幕要比傳統(tǒng)的方式慢一幀(16.7ms)。
我覺得第1點(diǎn)造成的影響最大,恰恰卻是最技術(shù)/設(shè)備無關(guān)的。如果微博app或者Android系統(tǒng)要改變,很容易就可以調(diào)得跟iOS一模一樣。但正是由于這是產(chǎn)品形態(tài)上的差別而不是純粹技術(shù)上的優(yōu)劣,反倒成了Android最不太可能改變的。
第2點(diǎn)的影響其次,當(dāng)然是指在目前這個(gè)大部分時(shí)候都能滿幀的情況下。這方面是Android從早期到現(xiàn)在進(jìn)步最明顯的方面,使用了很多方法來優(yōu)化幀率。但就算現(xiàn)在Android進(jìn)化了很多,硬件性能也進(jìn)化了很多,卻仍舊不可能徹底消滅掉幀的情況。
第3點(diǎn)通俗的講就是跟手性,跟手性的重要性不言而喻,但現(xiàn)在的差別比較細(xì)微,且具體數(shù)據(jù)我也不清楚。
我想過一個(gè)辦法讓桌面、微博這種內(nèi)容和手一起動(dòng)的應(yīng)用繪制到屏幕的速度快一幀(16.7ms),其實(shí)就是抵消之前提到的慢的那一幀,需要framework層和app層一起配合改動(dòng),目前已申請(qǐng)了專利但代碼還沒進(jìn),將來有時(shí)間了應(yīng)該會(huì)進(jìn)到MIUI。感興趣的可以看看專利:滑動(dòng)操作響應(yīng)方法、裝置及終端設(shè)備。
最后我來用專業(yè)技術(shù)分析一下微博app在Android里掉幀的原因。非編程人員可以不看下去了。(這個(gè)過程我使用的是小米3高通版+最新版微博app。)
最初,我認(rèn)為這種現(xiàn)象很像GC(垃圾回收)導(dǎo)致的,于是打開logcat觀察每次卡頓的時(shí)候有沒有GC發(fā)生。結(jié)果發(fā)現(xiàn)并沒有。停下來的時(shí)候才會(huì)有GC,這說明微博app在滑動(dòng)過程中控制得不錯(cuò),在停下來的一刻才去分配內(nèi)存,使GC不影響幀率。
然后我打開“開發(fā)者選項(xiàng)”->“GPU呈現(xiàn)模式分析”->“在屏幕上顯示為條形圖”(好像是4.4才有這個(gè)選項(xiàng),之前的只能在dumpsys里看),這會(huì)在屏幕上直觀的顯示每幀繪制花費(fèi)的時(shí)間。屏幕上有條基準(zhǔn)線大概是16ms,如果超過這條線則很有可能掉幀了。如果下面的藍(lán)色部分很長(zhǎng)則說明是軟件draw的部分太費(fèi)時(shí),那么可以通過traceview來繼續(xù)分析draw的java代碼。(我假定了現(xiàn)在的app都是硬件加速的方式。)如果中間紅色部分很長(zhǎng)則說明是OpenGL ES繪制過程太費(fèi)時(shí)。可以用gltrace來分析OpenGL ES的調(diào)用過程。
打開選項(xiàng)后使用微博app,發(fā)現(xiàn)雖然偶爾有超基準(zhǔn)線,但并不嚴(yán)重,并且卡頓的時(shí)候并沒有明顯異常。
于是我開始使用systrace,這下就很明顯了:
可以發(fā)現(xiàn)每隔幾幀,就會(huì)有一次大間隙,圖中我圈了紅圈圈的兩個(gè)地方都明顯超過正常的耗時(shí)時(shí)間。現(xiàn)在問題是,這些地方的代碼在干什么呢?是什么花費(fèi)了這么長(zhǎng)時(shí)間?
放大后發(fā)現(xiàn)都是這兩個(gè):obtainView和setupListItem。它們都是在draw之前調(diào)用的,這也解釋了通過上一步的方法(“GPU呈現(xiàn)模式分析”)為什么沒有顯示出來,因?yàn)槟莻€(gè)方法只展示draw里面的時(shí)間消耗。
通過在源碼里搜索obtainView和setupListItem,可以發(fā)現(xiàn)是AbsListView的obtainView方法和ListView的setupChild方法打下的這個(gè)log。
接下來,我們用traceview來看看這兩個(gè)方法里面究竟調(diào)用了什么代碼導(dǎo)致耗時(shí)過長(zhǎng)。
跟蹤obtainView最終到了這里:
代碼混淆了,看不太出來了,也懶得再跟下去了。但隨便點(diǎn)了點(diǎn)然后看到:
TextView.setText用了挺多的時(shí)間。感覺Android團(tuán)隊(duì)?wèi)?yīng)該優(yōu)化優(yōu)化這個(gè)方法。
然后再來跟蹤setupChild方法:
都是measure占用的時(shí)間,并且調(diào)用次數(shù)比較多。這應(yīng)該說明了View的數(shù)量不少。用hierarchyviewer看了下,的確不少,一條微博有50多個(gè)View:
結(jié)論:我們最終大致找到了耗時(shí)的代碼及部分原因。這兩個(gè)耗時(shí)方法應(yīng)該都是有可能減下來的,但應(yīng)該不那么容易。
在Android上實(shí)現(xiàn)功能比較容易,但如果默認(rèn)實(shí)現(xiàn)有了性能問題,要想解決就不好說了,有時(shí)候要繞很遠(yuǎn)。
最后,列一些相關(guān)鏈接:
Android圖形架構(gòu)(繪圖慢一幀的事情這里有說):http://source.android.com/devices/graphics/architecture.html
Android Performance Case Study:http://www.curious-creature.org/docs/android-performance-case-study-1.html
轉(zhuǎn)載需注明出處:http://cnblogs.com/zhucai/
我的微博:http://weibo.com/zhucai
標(biāo)簽: android, graphics, performance 綠色通道: 好文要頂 關(guān)注我 收藏該文 與我聯(lián)系 朱才關(guān)注 - 1
粉絲 - 18 榮譽(yù): 推薦博客 +加關(guān)注 0 0 (請(qǐng)您對(duì)文章做出評(píng)價(jià)) ? 上一篇: 二維坐標(biāo)圖
? 下一篇: MIUI 6的毛玻璃效果的技術(shù)實(shí)現(xiàn)(實(shí)時(shí)模糊)
posted @ 2014-08-10 17:38 朱才 閱讀( 7529) 評(píng)論( 2) 編輯 收藏
發(fā)表評(píng)論 回復(fù)引用 #1樓 2015-02-13 10:17 | Elta 昨天看到了你的這篇博文,想和你說一下我在使用應(yīng)用的時(shí)候發(fā)現(xiàn)的一個(gè)卡頓現(xiàn)象。
軟件:Adobe reader
具體現(xiàn)象:在看PDF文件時(shí),食指按住屏幕上下滑動(dòng),一開始的時(shí)候很流暢,在不松開手指的情況下反復(fù)上下滑動(dòng),開始出現(xiàn)卡頓現(xiàn)在。用手機(jī)帶的條形圖沒有發(fā)現(xiàn)有掉幀。不會(huì)再向下分析了,很好奇這是什么原因?qū)е碌?#xff0c;是否有辦法規(guī)避這個(gè)問題呢? 支持(0) 反對(duì)(0)
回復(fù)引用 #2樓 [ 樓主] 2015-03-03 08:51 | 朱才 @Elta
那可以估計(jì)出是繪圖之間的時(shí)間導(dǎo)致的。可以用systrace來繼續(xù)分析。 支持(0) 反對(duì)(0)
刷新評(píng)論 刷新頁面 返回頂部 發(fā)表評(píng)論
昵稱:
評(píng)論內(nèi)容:注銷 訂閱評(píng)論
[使用Ctrl+Enter鍵快速提交]
【推薦】50萬行VC++源碼: 大型組態(tài)工控、電力仿真CAD與GIS源碼庫(kù)【熱門】支持Visual Studio2015的葡萄城控件新品發(fā)布暨夏季促銷
最新IT新聞:
· 禁令解除:國(guó)內(nèi)主機(jī)游戲就能復(fù)活?
· 高通取得無線充電技術(shù)新突破:支持金屬機(jī)身手機(jī)
· Twitter盤后大跌12% 臨時(shí)CEO言論嚇壞投資者
· 在線超新星搜尋項(xiàng)目啟動(dòng) 在家就能搞科研
· 希臘前財(cái)政部長(zhǎng)承認(rèn)授權(quán)侵入國(guó)家稅收數(shù)據(jù)庫(kù)
? 更多新聞... 最新知識(shí)庫(kù)文章:
· 通過心理學(xué)知識(shí)提高問題定位與解決能力(上)
· 用醫(yī)生的思考方式調(diào)試你的代碼
· 代碼審查的價(jià)值——為何做、何時(shí)做、如何做?
· 所有程序員都應(yīng)該遵守的11條規(guī)則
· RESTful架構(gòu)詳解
? 更多知識(shí)庫(kù)文章... 昵稱: 朱才
園齡: 6年3個(gè)月
榮譽(yù): 推薦博客
粉絲: 18
關(guān)注: 1 +加關(guān)注
| |||||||||
| 28 | 29 | 30 | 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 | |||
| 12 | 13 | 14 | 15 | 16 | 17 | 18 | |||
| 19 | 20 | 21 | 22 | 23 | 24 | 25 | |||
| 26 | 27 | 28 | 29 | 30 | 31 | 1 | |||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | |||
搜索
?常用鏈接
- 我的隨筆
- 我的評(píng)論
- 我的參與
- 最新評(píng)論
- 我的標(biāo)簽
- 更多鏈接
我的標(biāo)簽
- android(4)
- canvas(3)
- graphics(3)
- html5(2)
- LambdaParser(2)
- delegate(2)
- js(2)
- json(1)
- Lambda(1)
- DataContractJsonSerializer(1)
- 更多
隨筆檔案
- 2015年7月 (1)
- 2014年12月 (2)
- 2014年8月 (1)
- 2011年10月 (1)
- 2011年2月 (1)
- 2010年8月 (1)
- 2010年7月 (2)
- 2010年6月 (1)
- 2010年5月 (2)
- 2010年1月 (1)
- 2009年12月 (1)
- 2009年10月 (2)
- 2009年7月 (1)
- 2009年6月 (1)
- 2009年5月 (3)
鏈接
- 我的微博
最新評(píng)論
- 1. Re:Android中app卡頓原因分析示例
- @Elta那可以估計(jì)出是繪圖之間的時(shí)間導(dǎo)致的。可以用systrace來繼續(xù)分析。...
- --朱才
- 2. Re:Android中app卡頓原因分析示例
- 昨天看到了你的這篇博文,想和你說一下我在使用應(yīng)用的時(shí)候發(fā)現(xiàn)的一個(gè)卡頓現(xiàn)象。軟件:Adobe reader具體現(xiàn)象:在看PDF文件時(shí),食指按住屏幕上下滑動(dòng),一開始的時(shí)候很流暢,在不松開手指的情況下反復(fù)上......
- --Elta
- 3. Re:MIUI 6的毛玻璃效果的技術(shù)實(shí)現(xiàn)(實(shí)時(shí)模糊)
- framework層?
- --專注-
- 4. Re:動(dòng)態(tài)計(jì)算表達(dá)式
- 好厲害 舉一反三哇
- --z5337
閱讀排行榜
- 1. C#與Java的比較(17406)
- 2. Android中app卡頓原因分析示例(7529)
- 3. 用HashSet代替List(6034)
- 4. js中用gb2312編碼解碼(4858)
- 5. 我開發(fā)的幾個(gè)chrome擴(kuò)展(3901)
評(píng)論排行榜
- 1. 我開發(fā)的幾個(gè)chrome擴(kuò)展(38)
- 2. C#與Java的比較(17)
- 3. 用HashSet代替List(16)
- 4. out參數(shù)的失控(13)
- 5. LambdaParser:解析代碼字符串為L(zhǎng)ambda表達(dá)式并編譯為委托(13)
推薦排行榜
- 1. 乒乓球的運(yùn)動(dòng)模擬(7)
- 2. LambdaParser的實(shí)現(xiàn)(4)
- 3. C#與Java的比較(4)
- 4. 我開發(fā)的幾個(gè)chrome擴(kuò)展(3)
- 5. 動(dòng)態(tài)計(jì)算表達(dá)式(3)
總結(jié)
以上是生活随笔為你收集整理的Android中app卡顿原因分析示例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 几句禅语的解释
- 下一篇: C语言实验——求两个整数之中较大者