对于大多数实际目的而言,两种方法都没有显著的性能影响。如果您需要填充大量特定布局的情况下可能会有所影响,此时您可以尝试自行进行基准测试以查看是否存在任何真正的差异,但除此之外,我很难想象出一个会导致显著影响的场景。
假设您有一个布局:
<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>
发生的事情是,Android将此文件编译为二进制格式并打包到APK中。当您在运行时使用 LayoutInflater
时,它会将此二进制格式的块加载到内存中并解析它,并从其中构建视图层次结构,非常类似于您手动在代码中完成的操作。所有这些解析都在本地代码中完成,因此它们很可能比Java中的典型XML解析要优化得多。
LayoutInflater
遇到标记(例如,<Button .../>
)时,使用反射构造视图。第一次必须查找该特定视图的构造函数;之后,它将缓存构造函数以便以后更快地访问。button.setText(...)
、button.setBackground(...)
等),而视图通常在自己的膨胀期间调用这些方法。也就是说,通过视图的构造函数遍历的代码路径将根据从二进制 XML 格式解析出的属性执行这些变异。这是因为 LayoutInflater
使用接受 AttributeSet
的两个参数的构造函数。这里的含义是,当您手动构建视图时,某些方法可能会被调用两次。Context
调用只有一个参数的构造函数,仍会得到带有默认背景的 Button
。换句话说,代码路径包括调用 setBackground(...)
(或一些等效方法)以获取默认背景图像。然后稍后您必须自己使用 XML 文件中命名的自定义可绘制资源调用 setBackground(...)
。很难一口气说出这对影响的影响,因为它实际上取决于各个视图的实现和您所做的变异。setBackground()
)所节省的代价更高。 - FlyingPumbanew
)也会增加一些开销。然而,我认为这很无关紧要:如果你要填充 500 或 5000(或更多)的任何东西,你应该使用 RecyclerView
并回收视图。 - KarakuriListView
或RecyclerView
中使用时出现抖动。对于RecyclerView
,仅在第一次膨胀布局文件时才会发生这种情况。 - UdaraWanasinghe