Android面試一天一題(11 Day)

遇到一個從快播出來的Android開發,有11年的開發經驗,咋一看不管是資歷還是經歷都挺嚇人的。但和他共處一段時間后,發現他完全沒有體現出11年工作經驗的優勢,相反還常常犯一些低級的錯誤,如在ListView中加載本地的圖片(大圖)時不使用異步線程,而是直接setImageResource。而他工作和為人都很努力,對分配的工作都很認真,但效果卻常常不盡如人意,不管是和Android特性相關的代碼還是純邏輯的代碼,他都常常犯一些低級的錯誤(這些錯誤都是普遍認為一個11年工作經驗的人不應該犯的)。

后來我經常思考,是什么樣的原因導致一個人的工作年限和水平并不能成正比。我想到有兩個方面:

  1. 看待問題的眼界過窄,只能看到當前的可見的問題。(或者說他思考問題的角度和方式有較大的局限)
  1. 技術的要點沒有掌握,常常找不到合理的解決問題的方案。

這兩點都是需要慢慢地提升和積累,當一個人長時間在思維和眼界上沒有進步,技術也只懂些皮毛(或者只是會用),那么他工作越長時間他的優勢反而越不明顯,甚至變成劣勢。

面試題:如何優化ListView的性能?

在回答這個問題前,我認為很有必要和大家講幾點和getView相關的問題。我們設置或者優化ListView的性能很多時候都是在getView中完成的,反過來說就是很多性能問題都是由于沒有正確使用getView造成的。

public View getView(int position, View convertView, ViewGroup parent)

所以我們不妨先思考一下如下的幾個問題:

在一次顯示ListView的界面時,getView會被執行幾次?

每次getView執行時間應該控制在多少毫秒之內?

getView中設置listener要注意什么?

首先我們要知道ListView的ItemView有一個復用機制,簡單看如下圖所示,ListView中有一個RecycleBin類復負回收不可見且可能被再次使用的ItemView,由ScrapView存儲。


所以我在們設置Listener進就要注意,使用convertView時需要重新設置一個Listener,保括一些數據也需要重設置,不然可能會顯示之前那個ItemView在回收前的狀態。

在繪制ListView前往往要計算它的高度,所以一個ListView界面上可以看到6個ItemView,但是getView的執行次數卻有可能是12次,多出的次數用來計算高度(這個可以通過設置ListView的height為0來避免)。所以要避免在getView中進行邏輯運算,兩次計算同一邏輯完全是浪費。

每個getView的執行時間更是少得可憐,很多人可能對這個時間沒有概念,我可以簡單的給大算一下:

1秒之內屏幕可以完成30幀的繪制,人才能看到它比較流暢(蘋果是接近60幀,高于60之后人眼也無法分辨)。
每幀可使用的時間:1000ms/30 = 33.33 ms
每個ListView一般要顯示6個ListItem,加上1個重用convertView:33.33ms/7 = 4.76ms

即是說,每個getView要在4.76ms內完成工作才會較流暢,但是事實上,每個getView間的調用也會有一定的間隔(有可能是由于handler在處理別的消息),UI的handler處理不好的話,這個間隔也可難會很大(0ms-200ms)。結論就是,留給getView使用的時間應該在4ms之內,如果不能控制在這之內的話,ListView的滑動就會有卡頓的現象。

了解了這幾個問題,現在我們回來這次主要考查的面試題上,如何進行ListView的性能優化,讓它滑動更加流暢。大家一般常用如下方法:

  1. 重用ConvertView;
  1. 使用View Holder模式;
  2. 使用異步線程加載圖片(一般都是直接使用圖片庫加載,如Glide, Picasso);

我認為這些是面試者必備的知識點,如果連這些都說不清楚的話,也沒有必要再深入問了。針對面試者的回答,可以適當選一兩點追問一下,看是否真正明白。如:ViewHolder為什么能夠起到優化性能的作用?

除此之前還有一些優化建議:

  1. 在adapter的getView方法中盡可能的減少邏輯判斷,特別是耗時的判斷;
  1. 避免GC(可以從LOGCAT查看有無GC的LOG);
  2. 在快速滑動時不要加載圖片;
  3. 將ListView的scrollingCache和animateCache這兩個屬性設置為false(默認是true);
  4. 盡可能減少List Item的Layout層次(如可以使用RelativeLayout替換LinearLayout,或使用自定的View代替組合嵌套使用的Layout);

關于第4點,發現在一些型號的手機(如華為的P7)上特別管用,當其也優化都做完之后,有無這兩項設置滑動的卡頓情況有明顯不同。

<Listview
 android:scrollingCache="false" 
 android:animationCache="false"

小結

關于ListView有很多方面可以考察面試者,因為它實在是用的太頻繁了,雙方都能對某個問題點進行展開。如果一個面試者都沒有做過ListView優化,那么如果不是他寫的代碼太少就是他使用ListView加載的數據太簡單(可能只有幾十項),其本上沒有其他選項。所以這一題是很能看出面試者的項目經驗和實際的開發水平,屬于面試必考題之一。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容