App 性能優(yōu)化系列:
Android App 性能優(yōu)化(二)----內(nèi)存泄露(Memory Leak)
Android App 性能優(yōu)化(一)----布局優(yōu)化
一. 概述
布局優(yōu)化在 Android 性能優(yōu)化中占有舉足輕重的作用, 如果布局層次復雜,嵌套過深, 這樣的布局就會導致在測量繪制的時候更耗時, 占用更多內(nèi)存, 很容易就會出現(xiàn)卡頓. 如果布局層次分明合理, 沒有冗余View的布局, 不僅可以提高加載速度, 提供一個良好的用戶體驗, 還能使我們的代碼更容易維護和重用.
二. 具體的優(yōu)化方案
(1). 選擇合適的 ViewGroup
優(yōu)先考慮使用
ConstraintLayout
咨察,這也是google 推薦使用的布局ConstraintLayout
允許你在不嵌套的情況下復雜的布局,它與RelativeLayout
非常相似俺泣,所有的view都依賴于兄弟控件和父控件的相對關系,但是ConstraintLayout
比RelativeLayout
更加靈活.
目前通過 Android Studio 新建一個 layout xml 時默認的就是ConstraintLayout
, 使用它可以有效減少了布局的層級,大幅提高性能.
由于 Android 的碎片化程度高,手機屏幕尺寸眾多,使用ConstraintLayout
能構建出多屏幕適配性更好的布局.
ConstraintLayout使用介紹盡量多使用
RelativeLayout
和LinearLayout
,不要使用絕對布局AbsoluteLayout
;
在布局層次一樣的情況下, 建議使用LinearLayout
代替RelativeLayout
, 因為LinearLayout
性能要稍高一點;
LinearLayout 比 RelativeLayout 快的根本原因是 RelativeLayout 需要對其子View 進行兩次 measure 過程, 而 LinearLayout 則只需一次 measure 過程席爽,所以顯然會快于 RelativeLayout,但是如果 LinearLayout 中有
weight
屬性啊片,則也需要進行兩次measure只锻,但即便如此,應該仍然會比 RelativeLayout 快一點紫谷。
-
RelativeLayout
的子View如果高度和RelativeLayout
不同齐饮,會引發(fā)效率問題,當子View很復雜時笤昨,這個問題會更加嚴重, 如果可以祖驱,盡量使用padding
代替margin
. - 在層級深度相同的情況下, 優(yōu)先使用
LinearLayout
和FrameLayout
而不是RelativeLayout
。
(2). 使用include, merge, ViewStub 標簽
1. **重用布局 **<include/>
<include/>
標簽可將布局中的公共部分提取出來供其他layout
瞒窒,以實現(xiàn)布局復用的目的, 這樣可以減少項目中重復的布局, 更能減少程序員的工作量.
比如include_progressbar.xml
這個布局app的很多頁面都會用到,這時就可以將它抽出來, 以便達到重用的目的;
include_progressbar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ProgressBar
android:id="@+id/pb"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="加載中..."/>
</LinearLayout>
在
activity_main.xml
中使用:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cjlcom.includetest.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World! Hello World! Hello World! Hello World!" />
<include
android:id="@+id/pb_main"
layout="@layout/include_progressbar">
</include>
</android.support.constraint.ConstraintLayout>
2. 合并布局<merge/>
有時我們在使用
<include/>
后可能會導致出現(xiàn)相同ViewGroup
的嵌套, 比如我們使用<include/>
要引入的布局的根布局為FrameLayout
, 并且引入之后該布局的父布局也是FrameLayout
, 這時最終的布局就會出現(xiàn)兩層相同F(xiàn)rameLayout布局, 這種 layout 節(jié)點是多余的捺僻,會導致解析變慢,解決辦法就是通過<merge/>
標簽去掉這多余的一層FrameLayout
節(jié)點.
還有一種比較特殊的情況就是根布局是FrameLayout
且不需要設置background或padding等屬性崇裁,可以用merge代替匕坯,因為Activity內(nèi)容試圖的parent view就是個FrameLayout,所以可以用merge消除只剩一個拔稳。
3. 按需加載<ViewStub/>
<viewstub/>
標簽同<include/>
標簽都可以用來引入一個外部布局葛峻,區(qū)別是<viewstub/>
引入的布局默認不會去繪制,從而在解析layout時加快速度和減少內(nèi)存開銷.
<viewstub/>
常用來引入那些默認不會顯示巴比,只在特殊情況下顯示的布局泞歉,如進度條布局逼侦、網(wǎng)絡加載失敗或者重試等刷新布局匿辩、信息出錯出現(xiàn)的提示布局等.
還有一種方法就是不需要立即加載的布局腰耙,設置visibility為GONE,系統(tǒng)會跳過铲球,不加載, 這種方法和<viewstub/>
區(qū)別后續(xù)說明.
(3). 使用<Space/>
控件
參考
[1] http://blog.csdn.net/hejjunlin/article/details/51159419