Android NDK开发详解之调试和性能分析的DEX 布局优化和启动配置文件

Android NDK开发详解之调试和性能分析的DEX 布局优化和启动配置文件

实验性:使用启动配置文件进行 DEX 布局优化是一项需要添加实验性标记的功能。

本文档介绍了在构建 Android 应用时可以通过哪些步骤启用使用启动配置文件进行 DEX 布局优化的功能。
重要提示:本文档假定您熟悉基准配置文件的相关工作流程。为了简化设置,请使用基准配置文件 Gradle 插件。
要求

如果想使用 DEX 布局优化及相关功能,您需要安装 Jetpack Macrobenchmarks 版本 1.2.0-alpha14 或更高版本,以及下表中所列的 Android Gradle 插件版本:
在这里插入图片描述

目前不支持 Bazel 等第三方构建系统。
启动配置文件

启动配置文件与基准配置文件类似。此类配置文件描述了对应用启动至关重要的类和方法,这些类和方法必须先做好加载准备。启动配置文件也使用与基准配置文件相同的人类可读格式 (HRF)。
注意:应用启动通常是多个关键 CUJ 的组合。对于简单的应用,您可以启动应用的 MainActivity。不过,您可能需要组合关键 CUJ,例如登录和其他重要的启动功能。

启动配置文件和基准配置文件之间的一个主要区别是,基准配置文件包含对应用启动以外的优化至关重要的类和方法,例如减少动画期间或应用启动以外的关键用户历程 (CUJ) 期间的卡顿。

启动配置文件和基准配置文件之间的另一个主要区别是,启动配置文件无法由库提供,也不受 Android Gradle 插件合并的约束。这是因为库不一定充分了解应用启动的关键类和方法有哪些。这些类和方法最好衍生自 Jetpack Macrobenchmark,并将 BaselineProfileRule 与专门针对应用启动的 CUJ(例如 collectStableBaselineProfile)结合使用。

请参阅下表,快速了解基准配置文件与启动配置文件之间的主要区别。
在这里插入图片描述

启动配置文件存储在 src//main/baselineProfiles/startup-prof.txt 中。
DEX 布局优化

这项优化能够改进启动期间所用代码的位置,缩短启动时间,从而减少应用启动期间发生的主要页面故障的数量。

为此,需要将启动期间要执行的所有代码添加到主要 classes.dex 文件中,同时将所有非启动代码从主要 classes.dex 文件中移除。
在这里插入图片描述

图 1. DEX 布局优化的代码位置改进。
使用 DEX 布局优化

本部分介绍了如何使用 DEX 布局优化。
构建启动配置文件

首先,您需要构建启动配置文件。
项目设置

在前面的示例中,插桩测试驱动了一个软件包名称为 com.example.app 的 app 模块。

当您使用 Jetpack Macrobenchmark 生成启动配置文件规则时,您会在 build 中定义新的基准变体。基准变体与发布变体相同,不过您会关闭缩减功能。

以下代码摘自应用模块的 build.gradle 文件。
Kotlin

buildTypes {
        ...
        create("benchmark") {
            initWith(buildTypes.getByName("release")
            isMinifyEnabled = false
            signingConfig = signingConfigs.getByName("debug")
            matchingFallbacks += "release"
        }
}

Groovy


buildTypes {
        ...
        create("benchmark") {
            initWith(buildTypes.getByName("release")
            isMinifyEnabled = false
            signingConfig = signingConfigs.getByName("debug")
            matchingFallbacks += "release"
        }
}

生成启动规则
Kotlin

@RunWith(AndroidJUnit4::class)
class StartupProfileGenerator {
    @get:Rule
    val baselineProfileRule = BaselineProfileRule()

    @Test
    fun startup() =
        baselineProfileRule.collectStableBaselineProfile(
            packageName = "com.example.app",
            includeInStartupProfile = true
    ) {
            // This scenario just starts the activity and waits for it to draw
            // the first frame. If you have animations or async content in your
            // startup, wait for them with UiAutomator.
            startActivityAndWait()
        }
}

Java

@RunWith(AndroidJUnit4::class)
class StartupProfileGenerator {
    @get:Rule
    val baselineProfileRule = BaselineProfileRule()

    @Test
    fun startup() =
        baselineProfileRule.collectStableBaselineProfile(
            packageName = "com.example.app",
            includeInStartupProfile = true
    ) {
            // This scenario just starts the activity and waits for it to draw
            // the first frame. If you have animations or async content in your
            // startup, wait for them with UiAutomator.
            startActivityAndWait()
        }
}

注意:虽然启动配置文件和基准配置文件共享 HRF 格式,但启动配置文件不参与合并,并且是 build 的显式输入。
输出

运行测试将会生成如下所示的文件:


HSPLandroidx/compose/runtime/ComposerImpl;->updateValue(Ljava/lang/Object;)V
HSPLandroidx/compose/runtime/ComposerImpl;->updatedNodeCount(I)I
HLandroidx/compose/runtime/ComposerImpl;->validateNodeExpected()V
PLandroidx/compose/runtime/CompositionImpl;->applyChanges()V
HLandroidx/compose/runtime/ComposerKt;->findLocation(Ljava/util/List;I)I
Landroidx/compose/runtime/ComposerImpl;

注意:进行启动 DEX 布局优化时,系统只会考虑启动 CUJ 生成的规则。这意味着系统将忽略通过合并库规则衍生的所有规则。

将输出文件的内容复制到 src/main/baselineProfiles/startup-prof.txt。

启用 DEX 布局优化

如需启用 DEX 布局优化,请使用以下 Gradle 代码段:
Kotlin

android {
    // ...
    experimentalProperties["android.experimental.art-profile-r8-rewriting"] = true
    experimentalProperties["android.experimental.r8.dex-startup-optimization"] = true
}

Groovy

android {
    // ...
    experimentalProperties["android.experimental.art-profile-r8-rewriting"] = true
    experimentalProperties["android.experimental.r8.dex-startup-optimization"] = true
}

android.experimental.art-profile-r8-rewriting

实验性属性 android.experimental.art-profile-r8-rewriting 支持通过 D8 和 R8 重写基准规则。

必须执行此步骤,因为 D8 和 R8 会执行类合并、合成、重写 lambda 以及方法签名优化等优化。

这些优化可以更改现有类的方法签名,并创建从现有源代码符号派生的新类。执行这些转换时,D8 和 R8 会对人类可读的基准和启动配置文件规则执行同一组转换。

此步骤对于全面捕获优化应用性能所需的所有规则非常重要。启用 R8 规则重写可将配置文件质量提高多达 25%。
注意:您还可以使用 experimental.art-profile-r8-rewriting 提高基准配置文件的配置文件质量。
android.experimental.r8.dex-startup-optimization

实验性属性 android.experimental.r8.dex-startup-optimization 支持 DEX 布局优化。
注意:启用此标记后,您会看到主要 DEX 文件将缩减为仅包含应用启动所需的类。如果应用之前从未使用过 MultiDex,则现在需要启用 MultiDex。

如需构建具有 DEX 布局优化功能的 APK,您可以使用以下代码:
./gradlew :app:assembleRelease
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五一编程

程序之路有我与你同行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值