文集目錄
ps:喜歡的點贊哦 android性能跟蹤分析工具系列 - 目錄
Hierarchy Viewer工具提供了一個可視化界面顯示布局的層次結構,讓我們可以進行調試,從而優(yōu)化界面布局結構。
不要小看這個工具啊,這可是必備工具啊,遙想當年,因為界面布局復雜,我寫的個人中心界面可是差不多2s 才顯示出來啊,優(yōu)化起來那叫一個痛苦啊,奈何 UI 給的設計圖太他媽復雜了,UI 自己都是瞎往上拖控件,他自己都不知道為了啥,就是知道你開發(fā)就是不能改,那排版反人類啊,好在現在有了 ConstraintLayout 約束布局,這個用好了簡直利器啊,一般人我可不告訴他哈。
閑話不多說,先來看看 Hierarchy Viewer 長啥樣子
整個工具分3個部分,左邊的是布局層次圖,使用滾輪可以放大縮小的,點擊具體的 view 是可以查看view 的3 measu/layout/draw 方法的耗時的,顏色部分,綠色是計算很快,黃色是計算速度在所有的view 中居中,50%的水平,紅色是計算很慢,是需要嚴重關注的。
右上角的是縮略圖不多說,右下角的是我們在層次圖中選中的 view 在整個界面的位置,紅框占中的就是,這里我選的是根視圖,所以把整個界面都包括進來了
注意啊,我們剛剛進來是需要選中根視圖,然后點擊我在上面用紅框圈中的按鈕,點一下就是重新計算,注意點一下就行,第一次計算才是頁面啟動時的用時,你再點都是刷新頁面的用時了
如何啟動
好了上面簡單說了下這個工具我們看哪,現在就來說說這個工具怎么打開
打開 Android devices trace ,之前介紹過了
在 DDMS 中我們點擊 Hierarchy Viewer ,然后選擇我們需要查看的進程就中的具體的某個頁面,再點這個Hierarchy Viewer按鈕
如何優(yōu)化布局層次
好了, 這個工具打開和使用都很簡單,主要的我們需要借助這個工具查看我們的頁面布局水平,要是發(fā)現效率低,必須優(yōu)化的,所以本篇的重點就來了,就是如何優(yōu)化布局層次,方法如下:
- 線性布局比相對布局有布局優(yōu)勢
在布局層級相同的情況下,相對布局比線性布局會多跑 measu 方法,效率第一點。這點效率優(yōu)勢比少一層布局層級來說要輕微許多。 - 使用ConstraintLayout 約束布局
約束布局的 view 相互定位方式真的太強大了,極端情況下,我們的內容布局用一層就可以 - 使用 ViewStub
在布局中有的 layout 我們可能很少顯示他,這樣 ViewStub ,stubView在不顯示時是不會參與布局相關計算的,屬于延遲加載的一種了。 - 使用 space 標簽
space 標簽繼承自 view,但是把 draw方法做了空實現,所以不會進行繪制 - 使用merge減少無用的父布局
merge使用起來有很多限制,具體使用機會比較少。
下面我說下比較容易忘的
ViewStub的使用
ViewStub是一個用于在運行時加載布局資源、不可見、寬高為0的View,在布局文件中使用它只是用于占位,在代碼中沒有手動加載它時,并不會影響頁面的測量、繪制、顯示效率,在代碼中通過inflate加載ViewStub時,ViewStub會用在布局文件中為其指定的布局文件來代替它自身,通過前面的解釋可想而知,ViewStub只能夠被inflate一次,一旦加載后ViewStub對象就會被置為空;ViewStub標簽有對應的java類ViewStub.java,通過閱讀源碼可以發(fā)現,確實在初始化的時候設置為隱藏、不繪制、寬高為0,并且它復寫了View的dispatchDraw和draw方法,這倆方法是空方法,沒有調用super的方法,也沒有執(zhí)行自己的代碼
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
mViewStub = (ViewStub) findViewById(R.id.view_show);
}
public void showViewStub(View view) {
// mSHowView是 vie2wstub 顯示之后獲得的 view 對象
if (mSHowView == null) {
mSHowView = mViewStub.inflate();
return;
}
mSHowView.setVisibility(View.VISIBLE);
}
恩,viewstub 使用很簡單,記得我們在 inflate() 之后會返回實體的 view,之后我們再顯示隱藏,操作的都是這個 view 了
space 標簽
space標簽可以只在布局文件中占位,不繪制,Space標簽有對應的java類Space.java,通過閱讀源碼可以發(fā)現,它繼承至View.java,并且復寫了draw方法,該方法為空,既沒有調用父類的draw方法,也沒有執(zhí)行自己的代碼,表示該類是沒有繪制操作的,但onMeasure方法正常調用,說明是有寬高的。這可是神器啦。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center"
android:text="TextView 1"
android:textColor="@android:color/black"
android:textSize="28dp"
android:background="@android:color/darker_gray"/>
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@android:color/black"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center"
android:text="TextView 2"
android:textColor="@android:color/black"
android:textSize="28dp"
android:background="@android:color/darker_gray"/>
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center"
android:text="TextView 3"
android:textColor="@android:color/black"
android:textSize="28dp"
android:background="@android:color/darker_gray"/>
</LinearLayout>
效果圖:
給第一個 space 設置背景色,實際是不會生效的,別忘了 space 的 draw方法可是空的