<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      安卓筆記俠

      專注安卓開發

      導航

      Android繪制優化(二)布局優化

      前言

      我們知道一個界面的測量和繪制是通過遞歸來完成的,減少布局的層數就會減少測量和繪制的時間,從而性能就會得到提升。當然這只是布局優化的一方面,那么如何來進行布局的分析和優化呢?本篇文章會給你一個滿意的答案。

      1.布局優化工具

      在講到如何去布局優化前,我們先來學習兩種布局優化的工具。

      1.1 Hierarchy Viewer

      Hierarchy Viewer是Android SDK自帶的可視化的調試工具,用來檢查布局嵌套和繪制的時間。需要注意的是在在Android的官方文檔中提到:出于安全考慮,Hierarchy Viewer只能連接Android開發版手機或是模擬器。
      首先我們在Android Studio中選擇Tools->Android->Android Device Monitor,在Android Device Monitor中選擇Hierarchy Viewer ,如下圖所示:


      選擇Hierarchy Viewer后會進出Hierarchy Viewer窗口,如下圖所示。

      Hierarchy Viewer中有4個四個子窗口,它們的的作用為:

      • Windows:當前設備所有界面列表。
      • Tree View:將當前Activity的所有View的層次按照高層到低層從左到右顯示出來。
      • Tree Overview:全局概覽,以縮略的形式顯示。
      • Layout View:整體布局圖,以手機屏幕上真實的位置呈現出來。單擊某一個控件,會在Tree Overview窗口中顯示出對應的控件。

      根據上面講到的Hierarchy Viewer的4個四個子窗口,我們可以很容易的查看我們布局控件的層級關系。當然Hierarchy Viewer還可以查看某一個View的耗時,我們可以選擇某一個View,然后單擊下圖紅色箭頭標識的按鈕,這里我們把他簡稱為Layout Time按鈕。


      從圖中可以看出被選中的RelativeLayout自身的Measure、Layout和Draw的耗時數據都為n/a。單擊Layout Time按鈕后,就可以查看View的耗時情況了,如下圖所示。

      QQ截圖20170324170337.pngQQ截圖20170324170337.png

      從圖中可以看出,被選中的LinearLayout給出了自身Measure、Layout和Draw的耗時,并且它所包含的View中都有了三個指示燈,分別代表當前View在Measure、Layout和Draw的耗時,綠色代表比其他50%View的同階段(比如Measure階段)速度要快,黃色則代表比其他50%View同階段速度要慢,紅色則代表比其他View同階段都要慢,則需要注意了。如果想要看View的具體耗時,則點擊該View就可以了。

      1.2 Android Lint

      Android lint是在ADT 16提供的新工具,它是一個代碼掃描工具,通過代碼靜態檢查來發現代碼出現的潛在問題,并給出優化建議。檢查的范圍主要有以下幾點:

      • Correctness 正確性
      • Security 安全性
      • Performance 性能
      • Usability 可用性
      • Accessibility 可達性
      • Internationalization 國際化

      Android Lint功能十分強大,這里我們只關注XML布局檢查,我們可以通過Android Studio的Analyze->Inspect Code來配置檢查的范圍,如下圖所示。

      點擊上圖的OK按鈕后,就會進行代碼檢查,檢查的結果如下圖所示。

      圖中列出了項目中出現的問題種類,以及每個問題種類的個數,問題種類包括我們前面提到的Correctness 、Internationalization 、Performance等。我們點擊展開最后的XML一項,點擊一個問題,就會出現如下圖的提示。

      可以看出給出了Namespace declaration is never used的提示,并指出了問題所在的文件和行數,我們點擊數字3,直接跳入到問題的代碼,發現如下代碼:

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/activity_main"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
          ...
      View Code

      第三行的Namespace 確實沒有被用到。如果想要自定義Android Lint的檢查提示,可以通過File->Settings->Editor->Inspections中來配置Android Lint,如下圖所示。

      從圖中可以發現,我們可以配置Android Lint檢查的范圍以及問題的嚴重等級。

      2.布局優化方法

      布局的優化方法很多,主要包括合理運用布局、Include、Merge、ViewStub,下面我們來一一對這些內容進行講解。

      2.1 合理運用布局

      我們常用的布局主要有LinearLayout、RelativeLayout和FrameLayout等,合理的使用它們可以使得Android繪制工作量變少,性能得到提高。我們來舉個簡單的例子。

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="horizontal">
          <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="布局優化" />
          <LinearLayout
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginLeft="10dp"
              android:orientation="vertical">
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Merge" />
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="ViewStub" />
          </LinearLayout>
      </LinearLayout>
      View Code

      上面的代碼用了兩個LinearLayout來進行布局,運行效果如下圖所示。


      我們用Hierarchy Viewer來查看層級情況,如下圖所示。

      可以看到我們的布局共有3層,一共含有5個View。如果我們用RelativeLayout來進行改寫呢?代碼如下所示。

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
          <TextView
              android:id="@+id/tv_text1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="布局優化" />
          <TextView
              android:id="@+id/tv_text2"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginLeft="10dp"
              android:layout_toRightOf="@id/tv_text1"
              android:text="Merge" />
          <TextView
              android:id="@+id/tv_text3"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_below="@id/tv_text2"
              android:layout_marginLeft="10dp"
              android:layout_toRightOf="@+id/tv_text1"
              android:text="ViewStub" />
      </RelativeLayout>
      View Code

      我們只用了一個RelativeLayout來進行布局。用Hierarchy Viewer來查看層級情況,如下圖所示。

      布局共有兩層,一共含有4個View。從這里我們就可以看出我們用RelativeLayout減少了一層的布局,當然這只是一個簡單例子,如果布局復雜,那么合理的用RelativeLayout來替代LinearLayout會減少很多層布局。
      如果根據上面的例子來看,RelativeLayout的性能是比LinearLayout低,因為RelativeLayout中的View的排列方式是基于彼此依賴的。但是在實際開發中面對的情況比較多,不能輕易的說誰的性能更好。一般情況下,但是如果布局層數較多時,推薦用RelativeLayout來實現。如果布局嵌套較多,推薦使用LinearLayout來實現。

      2.2 使用Include標簽來進行布局復用

      2.3 用Merge標簽去除多余層級

      Merge意味著合并,在合適的場景使用Merge標簽可以減少多余的層級。Merge標簽一般和Include標簽搭配使用

      merge標簽最好是來替代FrameLayout,或者是布局方向一致的LinearLayout,比如當前父布局LinearLayout的布局方向是垂直的,包含的子布局LinearLayout的布局方向也是垂直的則可以用merge標簽.

      2.4 使用ViewStub來提高加載速度

      一個很常見的開發場景就是我們想要一個布局時,并不是所有的控件都需要顯示出來,而是顯示出一部分,對于這種情況,我們一般采用的方法就是使用View的GONE和INVISIBLE,但是這種方法效率不高,雖然是達到了隱藏的目的,但是仍在布局當中,系統仍然會解析它們,我們可以用ViewStub來解決這一問題。
      ViewStub是輕量級的View,不可見并且不占布局位置。當ViewStub調用inflate方法或者設置可見時,系統會加載ViewStub指定的布局,然后將這個布局添加到ViewStub中,在對ViewStub調用inflate方法或者設置可見之前,它是不占布局空間和系統資源的,它主要的目的就是為目標視圖占用一個位置。因此,使用ViewStub可以提高界面初始化的性能,從而提高界面的加載速度。

      我們首先在布局中加入ViewStub標簽,布局代碼如下所示。
      
      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
        <ViewStub
            android:id="@+id/viewsub"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout="@layout/titlebar"/>
         ...
      </LinearLayout>
      
      ViewStub標簽中用android:layout引用了此前寫好的布局titlebar.xml。這時我們運行程序,ViewStub標簽所引用的布局是顯示不出來的,因為引該局還沒有加載到ViewStub中,接下來在代碼中使用ViewStub:
      
      public class MainActivity extends AppCompatActivity {
          private ViewStub viewsub;
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              viewsub= (ViewStub) findViewById(R.id.viewsub);
      //        viewsub.inflate();//1
              viewsub.setVisibility(View.VISIBLE);//2
          }
      }
      
      可以使用注釋1和注釋2處的代碼來將ViewStub引用的布局加載到ViewStub中,這樣引用的布局就顯示了出來。
      View Code

      在使用ViewStub時需要主要以下問題:

      • ViewStub只能加載一次,加載后ViewStub對象會被置為空,這樣當ViewStub引用的布局被加載后,就不能用ViewStub來控制引用的布局了。因此,如果一個控件需要不斷的顯示和隱藏,還是要使用View的Visibility屬性。
      • ViewStub不能嵌套Merge標簽。
      • ViewStub操作的是布局文件,如果只是想操作具體的View,還是要使用View的Visibility屬性。

      3.避免GPU過度繪制

      什么是過度繪制呢?我們來打個比方,假設你要粉刷房子的墻壁,一開始刷了綠色,接著又刷了黃色,這樣黃色就將綠色蓋住,也就說明第一次的大量粉刷工作白做了。同樣手機屏幕繪制也是如此,過度繪制是指在屏幕上某個像素在同一幀的時間內被繪制多次,從而浪費了GPU和CPU的資源。產生這一原因主要有兩個原因:

      • 在XML布局中,控件有重疊且都有設置背景。
      • View的OnDraw中同一區域繪制多次。

      過度繪制是不可避免的,但是過多的過度繪制會浪費很多資源,并且導致性能問題,因此,避免過度繪制是十分必要的。我們可以用Android系統中自帶的工具來檢測過度繪制。首先要保證系統版本在Android 4.1以上,接著在開發者選項中打開調試GPU過度繪制選項就可以進入GPU過度繪制模式,如下圖所示。

      這時屏幕會出現出各種顏色,主要有以下幾種,如下圖所示。

      各個顏色的定義為:

      • 原色: 沒有過度繪制 – 每個像素在屏幕上繪制了一次。
      • 藍色: 一次過度繪制 – 每個像素點在屏幕上繪制了兩次。
      • 綠色: 兩次過度繪制 – 每個像素點在屏幕上繪制了三次。
      • 粉色: 三次過度繪制 – 每個像素點在屏幕上繪制了四次。
      • 紅色: 四次或四次以上過度繪制 – 每個像素點在屏幕上繪制了五次或者五次以上。

      最理想的是藍色,一個像素只繪制一次,合格的頁面繪制是白色、藍色為主,綠色以上區域不能超過整個的三分之一,顏色越淺越好。

      避免過度繪制主要有以下幾個方案:
      1.移除不需要的background。
      2.在自定義View的OnDraw方法中,用canvas.clipRect來指定繪制的區域,防止重疊的組件發生過度繪制。

      posted on 2018-07-16 10:10  安卓筆記俠  閱讀(896)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 徐闻县| 乱熟女高潮一区二区在线| 国内自拍视频一区二区三区| 久久久久久性高| 午夜国产福利片在线观看| 免费国产一区二区不卡| 亚洲精品一区二区麻豆| 女人香蕉久久毛毛片精品| 亚洲欧美色一区二区三区| 骚虎三级在线免费播放| 久久成人国产精品免费软件| 国产精品午夜无码AV天美传媒 | 奇米777四色成人影视| 成人看的污污超级黄网站免费| 亚洲一区无码精品色| 性色av无码久久一区二区三区| 高清欧美性猛交xxxx黑人猛交| 91精品国产色综合久久不| 国产精品中文字幕久久| 中文字幕亚洲人妻系列| 边添小泬边狠狠躁视频| 亚洲人成人无码网WWW电影首页| 亚洲天堂一区二区三区四区 | 亚洲国产精品日韩AV专区| 成人av天堂网在线观看| 东港市| 欧美极品色午夜在线视频| 精品国产欧美一区二区三区在线| 国产精品久久久天天影视香蕉| 亚洲精品一区二区三天美| 国产在线精品一区二区三区| 日本久久一区二区三区高清| 亚洲精品动漫免费二区| 亚洲精品人妻中文字幕| 加勒比中文字幕无码一区| 国产精品久久久久aaaa| 香港特级三A毛片免费观看| 熟女少妇精品一区二区| 亚洲精品三区二区一区一| 亚洲精品宾馆在线精品酒店| 激情五月开心综合亚洲|