Android 不同佈局型別measure、layout、draw耗時對比
阿新 • • 發佈:2019-02-14
內容
RelativeLayout、LinearLayout、FrameLayout、ConstraintLayout這四種類型的measure、layout、draw耗時對比。
測試試圖結構:
測試方式
使用一個結構非常深的試圖結構,重複執行measure、layout、draw各1000次。計算耗時。
結果(單位:ms):
程式碼:
public class MainActivity extends Activity {
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewGroup root = new FrameLayout(this) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
long l = System.nanoTime();
super .onMeasure(widthMeasureSpec, heightMeasureSpec);
timeMillis += (System.nanoTime() - l);
if (++count == 1000) {
Log.e("cww", "finish measure: " + timeMillis);
} else {
if (count < 1000) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
view.requestLayout();
view.invalidate();
}
}, 0);
}
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
long l = System.nanoTime();
super.onLayout(changed, left, top, right, bottom);
timeMillis2 += (System.nanoTime() - l);
if (count == 1000) {
Log.e("cww", "finish layout: " + timeMillis2);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
long l = System.nanoTime();
super.dispatchDraw(canvas);
timeMillis3 += (System.nanoTime() - l);
if (count == 1000) {
Log.e("cww", "finish draw: " + timeMillis3);
}
}
};
setContentView(root);
for (int i = 0; i < 10; i++) {
FrameLayout rootLocal = new FrameLayout(this);
root.addView(rootLocal);
root = rootLocal;
}
view = new View(this);
root.addView(view);
}
View view;
private int count = 0;
private long timeMillis = 0;
private long timeMillis2 = 0;
private long timeMillis3 = 0;
總結
- 可以看出,各種佈局除了measure差別比較大外,layout和draw耗時差別不大。
- RelativeLayout在measure這一步耗時賊JB嚴重。是因為相對佈局需要給所有子View水平方向測量一次,再豎直方向測量一次,才能確定每個子View的大小。層級一旦太深,measure時間以指數上升。
- 如果可以,在不增加巢狀的情況下,儘量使用FrameLayout。FrameLayout能夠實現重心,通過Gravity來實現。別老愛用RelativeLayout的AlignParentxxx屬性
- LinearLayout如果子View的LayoutParams裡有使用weight屬性的話,measure時間和RelativeLayout幾乎接近,因為也需要給每個子View測量兩次。
- ConstraintLayout是Google新推出的一個佈局,在效能上比RelativeLayout好,比LinearLayout差一些。
- 儘量少寫層級深的佈局,能減少一個試圖節點就少一些measure時間,加油少年!