那些Android中的效能最佳化

來源:互聯網
上載者:User

標籤:


效能最佳化是一個大的範疇,如果有人問你在Android中如何做效能最佳化的,也許都不知道從哪開始說起。

首先要明白的是,為什麼我們的App需要最佳化,最顯而易見的時刻:使用者say,什麼狗屎,刷這麼久都沒反應,取關卸載算了。

這跟什麼有關,我們先蒼白的反駁下,尼瑪使用者裝置老舊網又爛,關我屁事,根本不用最佳化。可是,老闆拍板了,施壓給CTO,然後CTO又來找你:Y的今天必須給我想辦法最佳化了,不然不準回家。

好吧,為什麼從UI的表象上看,App又卡又慢而且還錯亂。我們試著來剖析下吧。

題外話:把minSDK改到4.0+,去特麼的low使用者,連手機都不願意換,還能指望它能給你帶來多少營收麼,直接pass掉吧。4.0前的系統bug不少,不能為了彌補這些bug而降低了整體的高效能。

好了,讓我們先從UI說起:

首先要明白的是UI的繪製流程:measure-layout-draw,measure與layout都需要for loop所有的子控制項,彙集起來才能完成繪製,布局。所以子控制項越多,所消耗的時間越長(inflate,layout_weight,relative,多層嵌套等),減少不必要的子控制項或層級,是相當有必要的。你可以通過merge,viewstub這些標籤來減少層級嵌套。如果你的空間觀念沒那麼好,可以用HierarchyViewer工具來檢查。

對於Listview或者GridView這種多item的組件來說,複用item可以減少inflate次數,通過setTag,getTag的ViewHolder方式實現複用,這裡要注意的是,holder中的控制項最好reset後再賦值,避免圖片,文字錯亂。

對於ViewPager第一次顯示時卡頓以及左右滑動卡頓,有以下幾種最佳化方式:

    • ViewPager同時緩衝page數最好為最小值3,如果過多,那麼第一次顯示時,ViewPager所初始化的pager就會很多,這樣pager累積渲染耗時就會增多,看起來就卡。

    • 每個pager應該只在顯示時才載入網路或資料庫(UserVisibleHint=true),最好不要預先載入資料,以免造成浪費

圖片顯示不出來或者載入時間太長,怎麼辦?分兩部分,下載速度,載入速度

    • 對於下載,要控制好同時下載的最大任務數(平均速度慢),同時給InputStream再包一層緩衝流會更快(如BufferedInputStream)。

    • 對於載入速度,我們要知道一點,雖然下載的圖片可能只有幾百K,但是decode成bitmap所佔用的記憶體可是成倍的,儘可能的減小圖片size是根本因素,讓服務端提供不同解析度的圖片才是最好的解決方案,記憶體總有耗盡的時刻,別老想著大解析度會更清晰,實際就只有150*150的空間,非給弄張1000*1000的圖片是不恰當的。另外論載入速度:記憶體>硬碟>網路,合理的使用記憶體緩衝也是關鍵。假如自己寫不好,沒關係,有那麼多開源的圖片緩衝架構,不用自己操心。

再說緩衝

有很多種緩衝方式,也不用Stay列舉了,我們要說的是搭配使用。

    • 比方說,以前我們一直在用強引用,HashMap,後來我們發現占記憶體,我們就用軟引用,弱引用來及時回收,再後來因為回收機制不可控,所以又有了lrucache,disklrucache通過演算法來平衡記憶體與硬碟緩衝。隨著android版本的推進與演化,我們也應該擁抱變化。如果你的App裡還有軟引用,弱引用的地方,不妨再check下。
    • 比方說網路+資料庫。網路我們一般都是去主動擷取,而非被動接受。那如果說資料是重複的或者未更改的呢?那我們去取一次網路資料有什麼意義呢?我的解決方案是給每個activity或fragment或每個組件設定一個最大請求間隔,比如一個listview,第一次請求資料時,儲存一份到資料庫,並記下時間戳記,當下次重新初始化時,判斷是否超過最大時間間隔(如5分鐘),如果沒有,只載入資料庫資料,不需要再做網路請求。當然,還有一些隱式的http請求架構會快取服務器資料,在一定時間內不再請求網路,或者當伺服器返回304時將之前緩衝的資料直接返回。

反正也說到網路了,那我們也來說說

    • 現在有很多現成HTTP架構供我們使用,我們幾乎只用寫配置就可以搞定一個url請求,但是這裡有很多需要服務端配合的,比如:json資料格式,WebP代替jpg,支援斷點續傳,多個請求合并成一個,盡量不做重新導向,伺服器緩衝以及負載平衡等。

    • 對用戶端本身,除了上述的實現,我們還需要合理的緩衝,控制最大請求並發量,及時取消已失效的請求,過濾重複請求,timeout時間設定,請求優先順序設定等。

最佳化可不是一個人的事,實現一個功能簡單,但是想最佳化重構,那是很不容易的事。需要多方面的預判與聯調。合理的假設與實踐是最佳化最重要的手段。

說完這些具體的點,我們再來說說一些常識,或者稱之為代碼規範。

    • 你要知道for loop中不要聲明臨時變數,不到萬不得已不要在裡面寫try catch。

    • 合理使用資料類型,比如StringBuilder代替String,(筆試題最常見的是str+="str"中有幾個對象) ,少用枚舉enum,少用父類聲明(List,Map)

    • 如果你有頻繁的new線程,那最好通過線程池去execute它們,減少線程建立開銷。

    • 你要知道單例的好處,並正確的使用它。

    • 多用常量,少用顯式的"action_key",並維護一個常量類,別重複聲明這些常量。

    • 如果可以,至少要弄懂設計模式中的策略模式,組合模式,裝飾模式,原廠模式,觀察者模式,這些能協助你合理的解耦,即使需求頻繁變更,你也不用害怕牽一髮而動全身。需求變更不可怕,可怕的是沒有在寫代碼之前做合理的設計。

當然還有很多很多,Stay所說的也只是一個大的輪廓,還是需要自己不斷的嘗試。會開發寫代碼跟會做產品的區別還是蠻大的,僅僅是態度就能刷死80%的碼農了。當你碰到一些需要最佳化的地方,耐心的去分析,時間的累積會讓你成為真正的工程師。

另外最佳化也沒有絕對的完美,每一次最佳化都是基於當前的環境來做的,要明白溝通是最好的最佳化,不盲從,不隨便,三思而後行。

Android上如何做效能最佳化的?大概寫三年代碼就能差不多知道了。

 

那些Android中的效能最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.