1. 程式人生 > >Android 不同佈局型別measure、layout、draw耗時對比

Android 不同佈局型別measure、layout、draw耗時對比

內容

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;

總結

  1. 可以看出,各種佈局除了measure差別比較大外,layout和draw耗時差別不大。
  2. RelativeLayout在measure這一步耗時賊JB嚴重。是因為相對佈局需要給所有子View水平方向測量一次,再豎直方向測量一次,才能確定每個子View的大小。層級一旦太深,measure時間以指數上升。
  3. 如果可以,在不增加巢狀的情況下,儘量使用FrameLayout。FrameLayout能夠實現重心,通過Gravity來實現。別老愛用RelativeLayout的AlignParentxxx屬性
  4. LinearLayout如果子View的LayoutParams裡有使用weight屬性的話,measure時間和RelativeLayout幾乎接近,因為也需要給每個子View測量兩次。
  5. ConstraintLayout是Google新推出的一個佈局,在效能上比RelativeLayout好,比LinearLayout差一些。
  6. 儘量少寫層級深的佈局,能減少一個試圖節點就少一些measure時間,加油少年!