For most practical intents and purposes, there is no significant performance impact to either approach. It might be relevant if you needed to inflate an incredibly large number of a particular layout, at which point you might try benchmarking it yourself to see if there's any real difference, but otherwise I'd be hard-pressed to envision a scenario that results in a significant impact either way.
Suppose you have a layout:
<LinearLayout xmlns:android="..."
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
... >
<Button
android:id="@+id/some_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/my_button_bg"
android:text="Hello World" />
<!-- other views ... -->
</LinearLayout>
What happens is Android compiles this file into a binary format and packages it in the APK. When you use LayoutInflater
at runtime, it will load a block of this binary format into memory and parse it, and build the view hierarchy from the contents, very similar to what you would do by hand in code. That parsing is all done in native code, so it's likely much more optimized than your typical XML parsing in java.
LayoutInflater
constructs the views using reflection when it encounters a tag (e.g. <Button .../>
). The first time it must look up the constructor for that particular view; thereafter it will cache the constructor for faster access later.
Where you would normally call mutators like button.setText(...)
, button.setBackground(...)
, etc., typically the views call these methods on themselves during inflation. That is, the code path being traversed through the view's constructor will perform those mutations based on the attributes parsed from the binary XML format. This is because LayoutInflater
uses the two-argument constructor which accepts an AttributeSet
. The implication here is that when you build views by hand, some of these methods may end up getting called twice.
For example, take the Button in the sample layout above. Buttons already have a default background (how this is actually provided is itself interesting, but not very important here), so even calling the one-argument constructor with just a Context
still gets you a Button
with the default background. In other words, the code path includes a call to setBackground(...)
(or some equivalent) with the default background image. Then later you have to call setBackground(...)
yourself with the custom drawable resource named in the XML file. It's difficult to say off hand what impact this has because it really depends on the implementation of individual views and what mutations you are making.
One final thought: I have built an app in a professional environment that avoided all use of XML (as much as possible, including things other than layouts). I can tell you without hesitation that it is immensely annoying and increases development time dramatically. I'm very good at it and it still takes far longer than doing it in XML. Additionally:
- The code tends to be extremely verbose
- You don't get the benefit of all the tooling built around XML layouts in the IDE
- Even without the tooling, just the XML file alone gives you a clear representation of the view hierarchy
- You may have to know about certain idiosyncrasies of the UI framework (some of which may depend on API level)
- It's not always possible to map an XML attribute to a corresponding mutator method in java (again sometimes depending on API level)
- Calculating dimensions gets a lot more interesting
- Remembering which LayoutParams to use where is great mental gymnastics
There are probably other reasons, but those are just off the top of my head. Don't get me wrong, there are plenty of times where manual manipulation of views and hierarchies is valuable, but I wouldn't substitute inflation for that.