作为一名 Android 开发者,不知道应用程序性能是通过编程方式声明布局还是通过 XML 声明布局更好,这让我很困扰。
我已阅读 this和 this关于 SO 的问题,但他们都没有回答我的问题:
哪个性能更高:以编程方式编写布局还是在 xml 文件中声明它们?
请注意,我只询问性能,不需要基于其他因素的答案。
此外,我正在寻找一个非常技术性的答案。如果需要,请提供指向 AOSP 代码的链接以证明您的答案(您可以假设 Android 版本是 Marshmallow)。更好的做法是向实验/论文/基准指出使用两种不同方式比较巨大布局的加载时间。
最佳答案
对于大多数实际 Intent 和目的,这两种方法都没有显着的性能影响。如果您需要膨胀大量的特定布局,这可能是相关的,此时您可以尝试自己对其进行基准测试,看看是否有任何真正的区别,但否则我很难想象一个结果的场景无论哪种方式都会产生重大影响。
假设您有一个布局:
<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
在运行时,它会将这种二进制格式的 block 加载到内存中并对其进行解析,并根据内容构建 View 层次结构,这与您在代码中手动执行的操作非常相似。该解析全部在 native 代码中完成,因此它可能比您在 Java 中的典型 XML 解析优化得多。
LayoutInflater
遇到标签时使用反射构造 View (例如 <Button .../>
)。第一次它必须查找该特定 View 的构造函数;此后它将缓存构造函数以便以后更快地访问。
您通常会在哪里调用像 button.setText(...)
这样的突变器, button.setBackground(...)
等,通常情况下, View 会在通货膨胀期间自行调用这些方法。也就是说,通过 View 的构造函数遍历的代码路径将根据从二进制 XML 格式解析的属性执行这些更改。这是因为 LayoutInflater
使用接受 AttributeSet
的双参数构造函数.这里的含义是,当您手动构建 View 时,其中一些方法最终可能会被调用两次。
例如,以上面示例布局中的 Button 为例。按钮已经有一个默认背景(实际上如何提供它本身很有趣,但在这里不是很重要),所以即使只用 Context
调用单参数构造函数仍然会给你一个Button
使用默认背景。换句话说,代码路径包括对 setBackground(...)
的调用。 (或一些等效的)与默认背景图像。然后你必须调用setBackground(...)
使用 XML 文件中命名的自定义可绘制资源。很难立即说出这会产生什么影响,因为它实际上取决于各个 View 的实现以及您正在进行的更改。
最后一个想法:我在专业环境中构建了一个应用程序,避免了所有 XML 的使用(尽可能多地,包括布局以外的东西)。我可以毫不犹豫地告诉您,这非常烦人,并且会显着增加开发时间。我非常擅长它,但它仍然比用 XML 做它花费的时间长得多。另外:
- 代码往往非常冗长
- 您无法从 IDE 中围绕 XML 布局构建的所有工具中受益
- 即使没有工具,仅 XML 文件就可以清楚地表示 View 层次结构
- 您可能需要了解 UI 框架的某些特性(其中一些可能取决于 API 级别)
- 并非总是可以将 XML 属性映射到 java 中相应的修改器方法(同样有时取决于 API 级别)
- 计算维度变得更有趣
- 记住在什么地方使用哪个 LayoutParams 是一项很棒的智力体操
可能还有其他原因,但这些只是我的脑海中浮现出来的。不要误会我的意思,很多时候手动操作 View 和层次结构很有值(value),但我不会用通货膨胀来代替它。
关于java - Android - 布局性能 : Programmatic vs XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35568058/