1. 程式人生 > >Android UI效能優化實戰 解決佈局複雜導致的程式奔潰

Android UI效能優化實戰 解決佈局複雜導致的程式奔潰

1、概述

2015年初google釋出了Android效能優化典範,發了16個小視訊供大家欣賞,當時我也將其下載,通過微信公眾號給大家推送了百度雲的下載地址(地址在文末,ps:歡迎大家訂閱公眾號),那麼近期google又在udacity上開了系列類的相關課程。有了上述的參考,那麼本效能優化實戰教程就有了堅實的基礎,本系列將結合例項為大家展示如何去識別診斷解決Android應用開發中存在的效能問題。那麼首先帶來的就是大家最關注的渲染的效能優化(~~渲染就是把東西繪製到螢幕上)。

ps:本部落格所有案例可能並不會完全按照Google給出的例子,因為範例程式碼比較多且不好在部落格中展示,所以基本程式碼都會經過調整,但表達的意思不會變。

2、 Android渲染機制

大家自己編寫App的時候,有時會感覺介面卡頓,尤其是自定義View的時候,大多數是因為佈局的層次過多,存在不必要的繪製,或者onDraw等方法中過於耗時。那麼究竟需要多快,才能給使用者一個流暢的體驗呢?那麼就需要簡單瞭解下Android的渲染機制,一圖勝千言:

Android系統每隔16ms發出VSYNC訊號,觸發對UI進行渲染,那麼整個過程如果保證在16ms以內就能達到一個流暢的畫面。那麼如果操作超過了16ms就會發生下面的情況:

如果系統發生的VSYNC訊號,而此時無法進行渲染,還在做別的操作,那麼就會導致丟幀的現象,(大家在察覺到APP卡頓的時候,可以看看logcat控制太,會有drop frames類似的警告)。這樣的話,繪製就會在下一個16ms的時候才進行繪製,即使只丟一幀,使用者也會發現卡頓的~~(ps:上面標識不應該是32ms麼,咋是34ms,難道我錯過了什麼)。

好了,很多朋友會不會奇怪為什麼是16ms,16ms意味著著1000/60hz,相當於60fps,那麼只要解釋為什麼是60fps,好在這個問題,網上有解答:

這是因為人眼與大腦之間的協作無法感知超過60fps的畫面更新。12fps大概類似手動快速翻動書籍的幀率,這明顯是可以感知到不夠順滑的。24fps使得人眼感知的是連續線性的運動,這其實是歸功於運動模糊的 
效果。24fps是電影膠圈通常使用的幀率,因為這個幀率已經足夠支撐大部分電影畫面需要表達的內容,同時能夠最大的減少費用支出。但是低於30fps是 
無法順暢表現絢麗的畫面內容的,此時就需要用到60fps來達到想要的效果,當然超過60fps是沒有必要的(據說Dart能夠帶來120fps的體驗)。本引用來源:

Google 釋出 Android 效能優化典範 - 開源中國社群

好了,有了對Android渲染機制基本的認識以後,那麼我們的卡頓的原因就在於沒有辦法在16ms內完成該完成的操作,而主要因素是在於沒有必要的layouts、invalidations、Overdraw。渲染的過程是由CPU與GPU協作完成,下面一張圖很好的展示出了CPU和GPU的工作,以及潛在的問題,檢測的工具和解決方案。

 
如果你對上圖感到不理解,沒關係,你只要知道問題:

  • 通過Hierarchy Viewer去檢測渲染效率,去除不必要的巢狀
  • 通過Show GPU Overdraw去檢測Overdraw,最終可以通過移除不必要的背景以及使用canvas.clipRect解決大多數問題。

如果你還覺得不能理解,沒關係,文字畢竟是枯燥的,那麼結合例項來展示優化的過程。

3、Overdraw的檢測

對於效能優化,那麼首先肯定是去發現問題,那麼對麼overdraw這個問題,還是比較容易發現的。 
按照以下步驟開啟Show GPU Overrdraw的選項:

設定 -> 開發者選項 -> 除錯GPU過度繪製 -> 顯示GPU過度繪製

好了,開啟以後呢,你會發現螢幕上有各種顏色,此時你可以切換到需要檢測的程式,對於各個色塊,對比一張Overdraw的參考圖:

那麼如果你發現你的app上深紅色的色塊比較多,那麼可能就要注意了,接下來就開始說如果遇到overdraw的情況比較嚴重我們該則麼處理。

4、Overdraw 的處理方案一:移除不必要的background

下面看一個簡單的展示ListView的例子:

  • activity_main
<code class="language-xml hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>
              <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
              <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
              <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingLeft</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/activity_horizontal_margin"</span>
              <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingRight</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/activity_horizontal_margin"</span>
              <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@android:color/white"</span>
              <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingTop</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/activity_vertical_margin"</span>
              <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingBottom</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/activity_vertical_margin"</span>
              <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"vertical"</span>
    ></span>

    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView
</span>        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:padding</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/narrow_space"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textSize</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/large_text_size"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_marginBottom</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/wide_space"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/header_text"</span>/></span>

    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">ListView
</span>        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/id_listview_chats"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@android:color/white"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:divider</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@android:color/transparent"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:dividerHeight</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/divider_height"</span>/></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span>></span>
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul>
  • item的佈局檔案
<code class="language-xml hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="utf-8"?></span>

<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"horizontal"</span>
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:paddingBottom</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/chat_padding_bottom"</span>></span>

    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">ImageView
</span>        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/id_chat_icon"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/avatar_dimen"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/avatar_dimen"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:src</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@drawable/joanna"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_margin</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/avatar_layout_margin"</span> /></span>

    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout
</span>        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@android:color/darker_gray"</span>
        <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"vertical"</span>></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">RelativeLayout
</span>            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@android:color/white"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"#78A"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"horizontal"</span>></span>

            <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_alignParentLeft</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"true"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:padding</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/narrow_space"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/hello_world"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"bottom"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/id_chat_name"</span> /></span>

            <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"wrap_content"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_alignParentRight</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"true"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:textStyle</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"italic"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/hello_world"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:padding</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/narrow_space"</span>
                <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/id_chat_date"</span> /></span>
        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">RelativeLayout</span>></span>

        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"match_parent"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:padding</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@dimen/narrow_space"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@android:color/white"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@string/hello_world"</span>
            <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"@+id/id_chat_msg"</span> /></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">LinearLayout</span>></span>
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul>
  • Activity的程式碼
<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.zhy.performance_01_render;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.os.PersistableBundle;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.support.annotation.Nullable;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.view.View;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.widget.ArrayAdapter;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.widget.ListView;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.widget.TextView;

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * Created by zhy on 15/4/29.
 */</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">OverDrawActivity01</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppCompatActivity</span>
{</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> ListView mListView;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> LayoutInflater mInflater ;

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(@Nullable Bundle savedInstanceState)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState);

        setContentView(R.layout.activity_overdraw_01);

        mInflater = LayoutInflater.from(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
        mListView = (ListView) findViewById(R.id.id_listview_chats);

        mListView.setAdapter(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayAdapter<Droid>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, Droid.generateDatas())
        {
            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> View <span class="hljs-title" style="box-sizing: border-box;">getView</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position, View convertView, ViewGroup parent)
            {

                ViewHolder holder = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(convertView == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>)
                {
                    convertView = mInflater.inflate(R.layout.chat_item,parent,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
                    holder = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ViewHolder();
                    holder.icon = (ImageView) convertView.findViewById(R.id.id_chat_icon);
                    holder.name = (TextView) convertView.findViewById(R.id.id_chat_name);
                    holder.date = (TextView) convertView.findViewById(R.id.id_chat_date);
                    holder.msg = (TextView) convertView.findViewById(R.id.id_chat_msg);
                    convertView.setTag(holder);
                }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
                {
                    holder = (ViewHolder) convertView.getTag();
                }

                Droid droid = getItem(position);
                holder.icon.setBackgroundColor(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x44ff0000</span>);
                holder.icon.setImageResource(droid.imageId);
                holder.date.setText(droid.date);
                holder.msg.setText(droid.msg);
                holder.name.setText(droid.name);

                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> convertView;
            }

            class ViewHolder
            {
                ImageView icon;
                TextView name;
                TextView date;
                TextView msg;
            }

        });
    }


}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li></ul>
  • 實體的程式碼
<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.zhy.performance_01_render;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.List;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Droid</span>
{</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String name;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> imageId;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String date;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String msg;


    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">Droid</span>(String msg, String date, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> imageId, String name)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.msg = msg;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.date = date;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.imageId = imageId;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.name = name;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> List<Droid> <span class="hljs-title" style="box-sizing: border-box;">generateDatas</span>()
    {
        List<Droid> datas = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<Droid>();

        datas.add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Droid(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Lorem ipsum dolor sit amet, orci nullam cra"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"3分鐘前"</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"alex"</span>));
        datas.add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Droid(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Omnis aptent magnis suspendisse ipsum, semper egestas"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"12分鐘前"</span>, R.drawable.joanna, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"john"</span>));
        datas.add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Droid(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"eu nibh, rhoncus wisi posuere lacus, ad erat egestas"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"17分鐘前"</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"7heaven"</span>));
        datas.add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Droid(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"eu nibh, rhoncus wisi posuere lacus, ad erat egestas"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"33分鐘前"</span>, R.drawable.shailen, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Lseven"</span>));

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> datas;
    }


}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul>

現在的效果是:

注意,我們的需求是整體是Activity是個白色的背景。

開啟Show GPU Overdraw以後:

對比上面的參照圖,可以發現一個簡單的ListView展示Item,竟然很多地方被過度繪製了4X 。 那麼,其實主要原因是由於該佈局檔案中存在很多不必要的背景,仔細看上述的佈局檔案,那麼開始移除吧。

  • 不必要的Background 1

    我們主佈局的檔案已經是background為white了,那麼可以移除ListView的白色背景

  • 不必要的Background 2

    Item佈局中的LinearLayout的android:background="@android:color/darker_gray"

  • 不必要的Background 3

    Item佈局中的RelativeLayout的android:background="@android:color/white"

  • 不必要的Background 4

    Item佈局中id為id_msg的TextView的android:background="@android:color/white"

這四個不必要的背景也比較好找,那麼移除後的效果是:

對比之前的是不是好多了~~~接下來還存在一些不必要的背景,你還能找到嗎?

  • 不必要的Background 5

這個背景比較難發現,主要需要看Adapter的getView的程式碼,上述程式碼你會發現,首先為每個icon設定了背景色(主要是當沒有icon圖的時候去顯示),然後又設定了一個頭像。那麼就造成了overdraw,有頭像的完全沒必要去繪製背景,所有修改程式碼:

            
           

相關推薦

Android UI效能優化實戰 解決佈局複雜導致程式

1、概述 2015年初google釋出了Android效能優化典範,發了16個小視訊供大家欣賞,當時我也將其下載,通過微信公眾號給大家推送了百度雲的下載地址(地址在文末,ps:歡迎大家訂閱公眾號),那麼近期google又在udacity上開了系列類的相關課程

Android UI效能優化實戰 識別繪製中的效能問題

                     1、概述2015年初google釋出了Android效能優化典範,發了16個小視訊供大家欣賞,當時我也將其下載,通過微信公眾號給大家推送了百度雲的下載地址(地址在文末,ps:歡迎大家訂閱公眾號),那麼近期google又在udacity上開了系列類的相關課程。有了上述的

[譯]Android UI 效能優化

。水平有限,翻譯不妥之處請多多指教。UI渲染是指從App生成幀並顯示在螢幕上的行為。為了保證使用者體驗的流暢性,App需要在16ms內渲染完一幀以達到60fps的幀率(為什麼是60fps?)。如果你的App UI渲染緩慢,那麼系統會強制跳過某些幀,使用者就會感知到介面的“口吃”,也就是卡頓。(以下三段Goog

Android 系統性能優化(34)---Android UI 效能優化

Android官網 Slow rendering;個人覺得非常有價值,比如指出 物件分配、垃圾回收(GC)、執行緒排程以及Binder呼叫 是Android系統中常見的卡頓原因,更重要的是給出了定位和解決這些問題的方案;而非簡單地告訴你避免物件分配,減少佈局層級,減少過度

Android UI效能優化 檢測應用中的UI卡頓

一、概述 在做app效能優化的時候,大家都希望能夠寫出絲滑的UI介面,以前寫過一篇部落格,主要是基於Google當時釋出的效能優化典範,主要提供一些UI優化效能示例: 實際上,由於各種機型的配置不同、程式碼迭代歷史悠久,程式碼中可能會存在很多在U

Android UI效能優化—過度繪製篇

Android UI效能優化——過度繪製篇 過度繪製(overdraw) 過度繪製介紹 每過幾年,就會有傳聞說某個博物館在用x光掃描一副無價的名畫之後,發現畫作的作者其實重用了老的畫布,在名畫的底下還藏著另一副沒有被發現的畫作。有時候,博物館還能用

SQL Server 效能優化實戰系列(一) SQL Server擴充套件函式的基本概念 使用SQL Server 擴充套件函式進行效能優化 SQL Server Url正則表示式 記憶體常駐 完美解決方案

資料庫伺服器主要用於儲存、查詢、檢索企業內部的資訊,因此需要搭配專用的資料庫系統,對伺服器的相容性、可靠性和穩定性等方面都有很高的要求。        下面是進行籠統的技術點說明,為的是讓大家有一個整體的概念,如果想深入可以逐個擊破;&n

Android UI效能專項測試及優化

1 UI卡頓(Jank) 內容的快速載入很重要,渲染的流暢性也很重要。android團隊把滯緩,不流暢的動畫定義為jank,一般是由於丟幀引起的。安卓裝置的螢幕重新整理率一般是60幀每秒(1/60fps=16.6ms每幀),所以你想要渲染的內容能在16ms內完

Android效能優化系列之佈局優化

在Android開發中,UI佈局可以說是每個App使用頻率很高的,隨著UI越來越多,佈局的重複性、複雜度也會隨之增長,這樣使得UI佈局的優化,顯得至關重要,UI佈局不慎,就會引起過度繪製,從而造成UI卡頓的情況,本篇部落格,我就來總結一下UI佈局優化的相關技巧。

Android App效能優化UI流暢度優化

一、卡頓的問題本質 UI流暢度的優化主要是解決UI卡頓的現象,而UI卡頓的源頭就是渲染效能的問題。佈局太複雜或者是一個元素重複繪製多次等原因,Android系統無法及時完成那些複雜的介面渲染操作,這樣就發生了丟幀,使用者就會感覺到不流暢,卡頓。 Androi

Android效能優化

Android的效能優化 寫在前面: 公司給了我一週的時間去學習Android效能的優化,參考了張明雲老師的一片文章,並且用公司的實際專案進行測試(附有截圖),還進行了一些知識點,注意事項以及很多網址連結的補充,希望這篇博文能讓做效能測試的朋友們少走一些彎路。

Android效能優化

眾所周知,android裝置作為一種移動裝置,不管是cpu還是記憶體都無法跟pc裝置相提並論。這就意味著我們不能無限制地使用記憶體和cpu的資源,過多地使用記憶體會導致oom,過多地使用cpu資源,做大量的耗時任務,會導致手機變得異常卡頓,甚至無法響應出現ANR。所以我們在平常做開發時,一定要注意效

Mysql效能優化實戰

1、索引設計規範 常見索引列建議: SELECT、UPDATE、DELETE語句的WHERE從句中的列 包含在ORDER BY、GROUP BY、DISTINCT中的欄位,建議聯合索引 多表JOIN的關聯列 索引列的順序: 區分度最高的列放在聯合索引的最左側 儘量把欄位長度

Android效能優化:電量消耗統計

電量的消耗和使用對於移動裝置非常重要,一項調查問卷顯示,電池的容量和壽命是手機最重要的營銷點:所謂“the one thing that you can't do without”。 硬體 從硬體的角度看,Android電量的消耗主要來自螢幕,CPU,網路裝置和各樣的感測器:指紋,亮度

效能優化實戰:百萬級WebSockets和Go語言

SegmentFault 首頁 問答 專欄 講堂 發現 搜尋 立即登入免費註冊

Android效能優化工具之Hierarchy Viewer使用總結

概述 Hierarchy Viewer提供了一個視覺化的介面來觀測佈局的層級, 讓我們可以優化佈局層級, 刪除多餘的不必要的View層級, 提升佈局速度. 應用Hierarchy Viewer 目前Hierarchy Viewer只能在root過的機器才能使用. 主要是在沒有ro

基於Spark UI效能優化與除錯——初級篇

Spark有幾種部署的模式,單機版、叢集版等等,平時單機版在資料量不大的時候可以跟傳統的java程式一樣進行斷電除錯、但是在叢集上除錯就比較麻煩了...遠端斷點不太方便,只能通過Log的形式進行資料分析,利用spark ui做效能調整和優化。 那麼本篇就介紹下如何利用Ui做效能分析,因為本人的經驗也不是很

Android App效能優化系列

Android App效能優化系列 關於Android App的優化,從第一篇的計劃開始,到記憶體優化的系列文結束,不知不覺近三個月的時間,寫了十五六篇相關的博文,算是對自己的知識的一個系統化,也希望能給大家一些幫助。 在此有對此做一個總結。 路線   Andro

Android效能優化問題

1、UI優化 在xml佈局檔案中,合理選擇RelativeLayout、LinearLayout、FrameLayout,其中RelativeLayout會讓子View呼叫兩次onMeasure()方法,並且佈局複雜時,onMeasure也相對複雜,效率比較低;在LinearLayout中

Android LeakCanary效能優化工具

效能優化工具(九)-LeakCanary 一、簡介 使用MAT來分析記憶體問題,有一些門檻,會有一些難度,並且效率也不是很高,對於一個記憶體洩漏問題,可能要進行多次排查和對比才能找到問題原因。 為了能夠簡單迅速的發現記憶體洩漏,Square公司基於MAT開源了L