title: Why does inflating an Android layout take so long?
body: <p>I have a dialog in Android. There is a noticeable lag when it opens. Here is what I did to investigate:</p>
  
  <ol>
  <li><p>Using crude timing with System.currentTime, my onCreateDialog method takes 150ms on a good day on 500-700ms on a regular day.</p></li>
  <li><p>I implemented my own LayoutInflator.Factory. My factory doesn't do anything. It simply returns null to let the default factory do the work. Yet it writes out the elapsed time since the last call. That way, I get a printout of how long each tag in the layout xml takes to inflate. Very surprisingly, each element takes about 20-70ms to inflate!</p></li>
  <li><p>I profiled the app. It appears that a lot of the time is indeed spent in the constructor of views or the LayoutParams.</p></li>
  <li><p>For a crude check, I measured the time to call the constructor on TextView with System.currentTime. It turns out in my emulator on a strong Alienware PC, it takes 20-70ms to instantiate a TextView object! Something seems to be amiss that it could take so long.</p></li>
  </ol>
  
  <p>For reference, there is a difference between layout inflation, measuring, and rendering. I'm only concerned with the performance for inflation right now.</p>
  
  <p>Here is how I implemented the LayoutInflator.Factory to take my measurements:</p>
  
  <pre><code>        LayoutInflater inflater = LayoutInflater.from(getActivity());
      LayoutInflater inflater2 = inflater.cloneInContext(getActivity());
      inflater2.setFactory(new LayoutInflater.Factory() {
  
          long inner = System.currentTimeMillis();
  
          @Override
          public View onCreateView(String name, Context context, AttributeSet attrs) {
              Log.d(LOG_TAG, "onCreateView: Called factory for " + name + " took " + (System.currentTimeMillis() - inner));
              inner = System.currentTimeMillis();
              return null;
          }
      });
  </code></pre>
  
  <p>Here is the output:</p>
  
  <pre><code>Called factory for TextView took 34
  Called factory for TextView took 30
  Called factory for android.support.constraint.Guideline took 76
  ...
  </code></pre>
  
  <p>Here is how I measured the time for instatiating a TextView and LayoutParams object.</p>
  
  <pre><code>    Log.d(LOG_TAG, "onCreateDialog: 10 " + (System.currentTimeMillis() - last));  last = System.currentTimeMillis();
  
      new TextView(getActivity());
      Log.d(LOG_TAG, "onCreateDialog: 11 " + (System.currentTimeMillis() - last));  last = System.currentTimeMillis();
  
      new ConstraintLayout(getActivity().getApplicationContext());
      Log.d(LOG_TAG, "onCreateDialog: 12 " + (System.currentTimeMillis() - last));  last = System.currentTimeMillis();
  </code></pre>
  
  <p>Here is my layout, but all layouts in the app seem to be affected by the slowness:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;ScrollView
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"&gt;
  
  &lt;android.support.constraint.ConstraintLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"&gt;
  
      &lt;TextView
          android:id="@+id/remote_message_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/remote_dialog_message"
          android:visibility="gone"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent"/&gt;
  
      &lt;TextView
          android:id="@+id/building_name_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:padding="8dp"
          android:textColor="#000"
          android:textSize="32sp"
          android:textStyle="bold"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/remote_message_text_view"
          tools:text="Bakery"/&gt;
  
      &lt;ImageView
          android:id="@+id/building_icon_image_view"
          android:layout_width="0dp"
          android:layout_height="wrap_content"
          android:adjustViewBounds="true"
          android:contentDescription="@string/building_icon_content_description"
          app:layout_constraintEnd_toEndOf="@+id/right_guide_line"
          app:layout_constraintStart_toStartOf="@+id/left_guide_line"
          app:layout_constraintTop_toBottomOf="@+id/building_name_text_view"
          tools:src="@drawable/bakery"/&gt;
  
      &lt;TextView
          android:id="@+id/action_heading_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:paddingEnd="8dp"
          android:paddingStart="8dp"
          android:paddingTop="8dp"
          android:text="@string/actions_heading"
          android:textAllCaps="true"
          android:textColor="#000"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/building_icon_image_view"/&gt;
  
      &lt;android.support.v7.widget.GridLayout
          android:id="@+id/action_grid_layout"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:paddingEnd="8dp"
          android:paddingStart="8dp"
          app:columnCount="3"
          app:layout_constraintTop_toBottomOf="@+id/action_heading_text_view"
          tools:layout_height="100dp"/&gt;
  
      &lt;TextView
          android:id="@+id/production_rules_heading_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:paddingEnd="8dp"
          android:paddingStart="8dp"
          android:paddingTop="8dp"
          android:text="@string/production_rules_heading"
          android:textAllCaps="true"
          android:textColor="#000"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/action_grid_layout"/&gt;
  
      &lt;TextView
          android:id="@+id/production_rules_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:paddingEnd="8dp"
          android:paddingStart="8dp"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/production_rules_heading_text_view"
          tools:text="1 flour creates 1 bread."/&gt;
  
      &lt;TextView
          android:id="@+id/production_speed_heading_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:paddingEnd="8dp"
          android:paddingStart="8dp"
          android:paddingTop="8dp"
          android:text="@string/production_speed_heading"
          android:textAllCaps="true"
          android:textColor="#000"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/production_rules_text_view"/&gt;
  
      &lt;TextView
          android:id="@+id/production_speed_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:paddingEnd="8dp"
          android:paddingStart="8dp"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/production_speed_heading_text_view"
          tools:text="1 peasant produces 1 unit per 60 minutes.\n(Add a peasant to cut the time to 30 minutes.)"/&gt;
  
      &lt;TextView
          android:id="@+id/countdown_heading_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:paddingEnd="8dp"
          android:paddingStart="8dp"
          android:paddingTop="8dp"
          android:text="@string/next_unit_count_down_heading"
          android:textAllCaps="true"
          android:textColor="#000"
          android:visibility="gone"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/production_speed_text_view"/&gt;
  
      &lt;TextView
          android:id="@+id/countdown_text_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:padding="8dp"
          android:textColor="#000"
          android:textSize="32sp"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/countdown_heading_text_view"
          tools:text="24 : 60 : 60"/&gt;
  
      &lt;android.support.constraint.Guideline
          android:id="@+id/left_guide_line"
          android:layout_width="0dp"
          android:layout_height="match_parent"
          android:orientation="vertical"
          app:layout_constraintGuide_begin="10dp"
          app:layout_constraintGuide_percent=".33"/&gt;
  
      &lt;android.support.constraint.Guideline
          android:id="@+id/right_guide_line"
          android:layout_width="0dp"
          android:layout_height="match_parent"
          android:orientation="vertical"
          app:layout_constraintGuide_percent=".66"/&gt;
  
  &lt;/android.support.constraint.ConstraintLayout&gt;
  </code></pre>
  
  <p></p>
  
  <p>Why is inflating the layout so slow. How can I speed it up?</p>