内容
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时间,加油少年!