安卓启动 性能提升 20-30% ,基准配置 入门教程

1.先从官方下载demohttps://github.com/android/codelab-android-performance/archive/refs/heads/main.zip

2.先用Android studio打开里面的baseline-profiles项目

3.运行一遍app,这里建议用模拟器,(Pixel 6 API 34)设备运行,因为基准配置 需要root权限,如果手机没有root,就用模拟器运行。

4.运行时会报This version (1.4.5) of the Compose Compiler requires Kotlin version 1.8.20 but you appear to be using Kotlin version 1.9.22 which is not known to be compatible.  Please consult the Compose-Kotlin compatibility map located at https://developer.android.com/jetpack/androidx/releases/compose-kotlin to choose a compatible version pair (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).

5.修改libs.versions.toml里的 kotlin = "1.9.22" 改为 kotlin = "1.8.20"

6.再运行一下,private fun NavBackStackEntry.lifecycleIsResumed() = this.getLifecycle().currentState == Lifecycle.State.RESUMED 这里的getLifecycle()会报错,改成lifecycle

7.再运行一次,这一次应该可以启动成功了,图片不显示可以忽悠不管,因为这个图片是从谷歌那边加载过来的,需要飞机,我们重点是基准配置,如果前面步骤碰见其他问题,基本与该项目无关,可以自行百度和AI解决。

8.点击File->new module 选择baseline profile generator ,如图,如果你是java党,可以右边改改配置,因人而异,我这里就选择默认的kotlin,直接点finish

9.如果你碰见 配置文件一片红,就删除,重新创建,放app下面,就不会爆红了,如果你没有遇见以下问题,可以跳过此步

如果删不掉,是因为app在引用,把这段去掉,点击sync now,再重新删一下

10.在baselineprofile的build.gradle.kts文件中修改,添加代码如下,代码解释:useConnectedDevices = false意思是否在真机上运行,由于真机没有root,只能在模拟器上运行,所以选择false就行,然后配置模拟器 ,记得导入

import com.android.build.api.dsl.ManagedVirtualDevice
import com.android.build.api.dsl.ManagedVirtualDeviceandroid {.......................
.......................targetProjectPath = ":app"testOptions.managedDevices.devices {create<ManagedVirtualDevice>("pixel6Api31") {device = "Pixel 6"apiLevel = 31systemImageSource = "aosp"}}
}// This is the configuration block for the Baseline Profile plugin.
// You can specify to run the generators on a managed devices or connected devices.
baselineProfile {managedDevices += "pixel6Api31"useConnectedDevices = false
}

如图下

11.在baselineprofile找到BaselineProfileGenerator类,自己项目可以根据自己情况更改,但是由于我们是demo,就演示一下,代码如下

  @Testfun generate() {// This example works only with the variant with application id `com.example.baselineprofiles_codelab`."rule.collect(packageName = "com.example.baselineprofiles_codelab",// See: https://d.android.com/topic/performance/baselineprofiles/dex-layout-optimizationsincludeInStartupProfile = true) {// This block defines the app's critical user journey. Here we are interested in// optimizing for app startup. But you can also navigate and scroll through your most important UI.// Start default activity for your apppressHome()startActivityAndWait()// TODO Write more interactions to optimize advanced journeys of your app.// For example:// 1. Wait until the content is asynchronously loaded// 2. Scroll the feed content// 3. Navigate to detail screen// 1. Wait until the content is asynchronously loaded.waitForAsyncContent()// 2. Scroll the feed content.scrollSnackListJourney()// 3. Navigate to detail screen.goToSnackDetailJourney()// Check UiAutomator documentation for more information how to interact with the app.// https://d.android.com/training/testing/other-components/ui-automator}}fun MacrobenchmarkScope.waitForAsyncContent() {device.wait(Until.hasObject(By.res("snack_list")), 5_000)val contentList = device.findObject(By.res("snack_list"))// Wait until a snack collection item within the list is rendered.contentList.wait(Until.hasObject(By.res("snack_collection")), 5_000)}fun MacrobenchmarkScope.scrollSnackListJourney() {val snackList = device.findObject(By.res("snack_list"))// Set gesture margin to avoid triggering gesture navigation.snackList.setGestureMargin(device.displayWidth / 5)snackList.fling(Direction.DOWN)device.waitForIdle()}fun MacrobenchmarkScope.goToSnackDetailJourney() {val snackList = device.findObject(By.res("snack_list"))val snacks = snackList.findObjects(By.res("snack_item"))// Select snack from the list based on running iteration.val index = (iteration ?: 0) % snacks.sizesnacks[index].click()// Wait until the screen is gone = the detail is shown.device.wait(Until.gone(By.res("snack_list")), 5_000)}

12.点击run按钮旁边三颗点,选择Edit Configurations...,然后点击左上角+,添加Gradle,在RUN下面一行添加:app:generateBaselineProfile -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile,点击OK就行,然后运行,如图:

如果出现> 'compileNonMinifiedReleaseJavaWithJavac' task (current target is 1.8) and 'compileNonMinifiedReleaseKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
  Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain

把compileOptions里的兼容版本改成对应的版本就行了,由于我是用的java 17,就改成17就行了,然后重新运行

compileOptions {sourceCompatibility = JavaVersion.VERSION_17targetCompatibility = JavaVersion.VERSION_17
}

如果没有出现上面问题,可以忽悠不管

13.运行大概需要等5-6分钟,如果太久了,建议重新运行一下,因设备而异,运行完成的话,在app项目的src->release->generated->baselineProfiles文件下,生成2个txt文件,一个是1.8W行-2.5W行的baseline-prof.txt文件和startup-prof.txt文件,因项目而异,如果基准配置更多,生成的可能更多,由于我们只生成了,异步加载,点击,滚动,差不多2W行

如图:

14. 使用模拟器测试速度,在 baselineprofile 的 build.gradle.kts下的defaultConfig 里添加 testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR",代码解释,这段是用来印制模拟器的错误

defaultConfig {minSdk = 28targetSdk = 34testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR"
}

15.在baselineprofile 项目的StartupBenchmarks类里添加和前面基准配置的 代码一样,模拟和基准操作

代码如下:

  private fun benchmark(compilationMode: CompilationMode) {// This example works only with the variant with application id `com.example.baselineprofiles_codelab`."rule.measureRepeated(packageName = "com.example.baselineprofiles_codelab",metrics = listOf(StartupTimingMetric()),compilationMode = compilationMode,startupMode = StartupMode.COLD,iterations = 10,setupBlock = {pressHome()},measureBlock = {startActivityAndWait()waitForAsyncContent()// 2. Scroll the feed content.scrollSnackListJourney()// 3. Navigate to detail screen.goToSnackDetailJourney()})}fun MacrobenchmarkScope.waitForAsyncContent() {device.wait(Until.hasObject(By.res("snack_list")), 5_000)val contentList = device.findObject(By.res("snack_list"))// Wait until a snack collection item within the list is rendered.contentList.wait(Until.hasObject(By.res("snack_collection")), 5_000)}fun MacrobenchmarkScope.scrollSnackListJourney() {val snackList = device.findObject(By.res("snack_list"))// Set gesture margin to avoid triggering gesture navigation.snackList.setGestureMargin(device.displayWidth / 5)snackList.fling(Direction.DOWN)device.waitForIdle()}fun MacrobenchmarkScope.goToSnackDetailJourney() {val snackList = device.findObject(By.res("snack_list"))val snacks = snackList.findObjects(By.res("snack_item"))// Select snack from the list based on running iteration.val index = (iteration ?: 0) % snacks.sizesnacks[index].click()// Wait until the screen is gone = the detail is shown.device.wait(Until.gone(By.res("snack_list")), 5_000)}

16.然后,直接右键运行,这个测试类,在模拟器(Pixel 6 API 31) 以上运行,我建议在模拟器(Pixel 6 API 34)运行,因为API31,可能会报下面错误,如果出现了,就切到API34

如果出现了java.lang.IllegalStateException: Error: did not detect tracing on after 5000 ms  ,我建议切换到模拟器(Pixel 6 API34),运行就不有问题17.运行效果如下

StartupBenchmarks_startupCompilationBaselineProfiles
timeToFullDisplayMs      min   821.2,   median   908.4,   max 1,114.1
timeToInitialDisplayMs   min   438.9,   median   514.8,   max   678.4
Traces: Iteration 0 1 2 3 4 5 6 7 8 9
Timed out waiting for process (com.example.baselineprofiles_codelab) to appear on Pixel_6_API_34 [emulator-5556].
WARNING: Running on Emulator
Benchmark is running on an emulator, which is not representative of
real user devices. Use a physical device to benchmark. Emulator
benchmark improvements might not carry over to a real user's
experience (or even regress real device performance).

StartupBenchmarks_startupCompilationNone
timeToFullDisplayMs      min   984.5,   median 1,157.2,   max 1,257.2
timeToInitialDisplayMs   min   498.9,   median   606.3,   max   668.4
Traces: Iteration 0 1 2 3 4 5 6 7 8 9

StartupBenchmarks_startupCompilationNone 表示没有基准上运行

StartupBenchmarks_startupCompilationBaselineProfiles 表示在有基准上运行

1,157.2 ->908.4,提升大概200毫秒,差不多百分之20多,到这里教程就结束了,谢谢大家

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/20058.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决使用go get 下载模块下载超时的问题

解决使用go get 下载模块下载超时的问题 使用go env可以看到&#xff0c;默认的GOPROXY的值是https://proxy.golang.org, 而https://proxy.golang.org在国内无法访问. 如果您使用的 Go 版本是 1.13 及以上, 可以使用以下命令解决 go env -w GO111MODULEon go env -w GOPROXY…

#window11设置系统变量#

在Windows命令行中&#xff0c;可以通过不同的命令和方法来查看和修改环境变量设置。以下是详细的步骤和命令&#xff1a; 1. 临时设置环境变量&#xff08;当前命令行窗口有效&#xff09; 查看环境变量&#xff1a;直接运行 set 命令&#xff0c;可以查看当前系统的全部环境…

思科防火墙 网线连接的端口还是down 已配置 端口还是down

环境&#xff1a; 思科防火墙fpr-2100 isco Firepower 2100 系列防火墙是思科系统&#xff08;Cisco Systems&#xff09;推出的一款中端网络安全和防火墙设备。这一系列的产品主要针对中到大型企业的需求&#xff0c;提供高性能的威胁防护和网络流量管理功能。 问题描述&am…

Java微服务智慧工地可视化SaaS云解决方案源码

智慧工地是指运用信息化手段&#xff0c;围绕施工过程管理&#xff0c;建立互联协同、智能生产、科学管理的施工项目信息化生态圈&#xff0c;并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析&#xff0c;提供过程趋势预测及专家预案&#xff0c;实现工程…

程序员兼中医爱好者对AI的看法

一.背景 因为社交媒体的发展&#xff0c;AI这个话题几乎跨越了社会各个阶层和行业&#xff0c;成了与性、吃饭并驾齐驱的热门话题。在没有特意去查阅资料的情况下&#xff0c;根据个人成长经历&#xff0c;作为一个自诩有智慧的人类一员来探讨这个问题。 二.AI的崛起是人类开始…

ftc基础编程:探索编程世界的基石

ftc基础编程&#xff1a;探索编程世界的基石 在当今数字化时代&#xff0c;编程已成为一项重要的技能。而ftc基础编程作为编程领域的入门课程&#xff0c;对于初学者来说具有至关重要的作用。本文将从四个方面、五个方面、六个方面和七个方面深入探讨ftc基础编程的重要性及其核…

排序算法之直接选择排序【图文详解】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;LiUEEEEE                        …

AI问答:供应链和产业链的区别

一、概念不同 1.1、理解供应链 供应链是指围绕核心企业&#xff0c;从配套零件开始&#xff0c;制成中间产品以及最终产品&#xff0c;最后由销售网络把产品送到消费者手中的、将供应商&#xff0c;制造商&#xff0c;分销商直到最终用户连成一个整体的功能网链结构。涉及一系…

基于tensorflow和NasNet的皮肤癌分类项目

数据来源 https://challenge.isic-archive.com/data/#2019 数据划分 写了个脚本划分 for line in open(ISIC/labels.csv).readlines()[1:]:split_line line.split(,)img_file split_line[0]benign_malign split_line[1]# 0.8 for train, 0.1 for test, 0.1 for validati…

快蜗牛OZON数据分析,OZON快蜗牛数据

在当今电商行业蓬勃发展的背景下&#xff0c;OZON作为俄罗斯及东欧市场的重要电商平台&#xff0c;其数据背后蕴藏着巨大的商业价值。快蜗牛&#xff0c;作为专注于OZON平台的数据分析工具&#xff0c;为卖家提供了深入的市场洞察和策略指导。接下来看看快蜗牛OZON数据分析&…

线上 | OpenSergo - [规范]

INDEX 1 参考资料2 OpenSergo 与 Sentinel 关系3 规范体系3.1 服务元数据ReportMetadataRequest 信息![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ffba569841ae4668b4cff74e4d41d21f.png)##### ReportMetadataReply 信息![在这里插入图片描述](https://img-blog…

BurpSuite2024.5

1 工具介绍 本版本更新介绍 此版本引入了Burp Scanner对WebSockets的支持、对记录登录编辑器的改进、WebSocket 匹配和替换规则以及许多性能改进。 Burp Scanner 支持 WebSockets 我们已更新内部代理的配置以允许 WebSocket 流量。这使 Burp Scanner 现在可以抓取依赖 WebSo…

基于大模型的智慧零售教育科研平台——技术方案

一、概述 1.1背景 随着数字经济的快速发展和全社会数字化水平的升级&#xff0c;人工智能的积极作用越来越凸显&#xff0c;人工智能与各个行业的深度融合已成为促进传统产业转型升级的重要方式之一。ChatGPT的出现掀起了又一波人工智能发展热潮&#xff0c;人工智能行业发展势…

Linux sudo用户权限管理小实验001

Linux sudo用户权限管理和审计-初步 1、设置历史指令的保存数量 默认history指令可以查看当前用户执行的1000条历史命令的条目 2、使用export指令设置HISTSIZE环境变量的数量为999999条。 3、基于date指令&#xff0c;输出日期和时间 4、设置linux系统history相关变量&…

js怎么根据出生日期计算年龄?js计算日期间隔

在用户主页信息展示中&#xff0c;有一个需求是根据用户填写的出生日期&#xff0c;计算出年龄&#xff0c;现用Javascript写一个方法进行实现。 // 根据出生日期计算年龄 // strBirthday: 出生日期字符串 1998-12-31 // 返回结果&#xff1a;0:同岁&#xff1b;-1:表示出生日期…

预编码算法(个人总结)

引言 预编码算法是现代无线通信系统中的关键技术&#xff0c;特别是在多输入多输出&#xff08;MIMO&#xff09;系统中。它们通过在发送端对信号进行处理&#xff0c;减少干扰并提高信道容量。这种技术广泛应用于5G、Wi-Fi和卫星通信系统中。本教程将详细介绍预编码算法的背景…

FV悬浮球,安卓真正小而美的神器,满足你的一切需求。

如果你问安卓最强软件有哪些&#xff0c;不同的人可能会有不同的答案&#xff0c;但如果是问我&#xff0c;那我的答案中一定会有他。 FV悬浮球 他是ES文件浏览器&#xff0c;原作者的新作品&#xff0c;经过几年的开发&#xff0c;拥有了超过400项功能&#xff0c;但大小只有…

GPT-4o:人工智能新时代的先锋

如何评价GPT-4o? 简介&#xff1a;最近&#xff0c;GPT-4o横空出世。对GPT-4o这一人工智能技术进行评价&#xff0c;包括版本间的对比分析、GPT-4o的技术能力以及个人感受等。提醒&#xff1a;在发布作品前&#xff0c;请把不需要的内容删掉。 方向一&#xff1a;对比分析 提…

java之SecureRandom

一、简介 SecureRandom 类用于生成加密安全的随机数。与 Random 类不同&#xff0c;SecureRandom 专为加密应用而设计&#xff0c;它提供了更强的随机数生成算法&#xff0c;如SHA1PRNG、NativePRNG等。这些算法通常基于密码学安全的伪随机数生成器&#xff08;PRNGs&#xff0…

如何在 llama.cpp 服务器中实现用户登录功能的优化方案?(语言-c++)

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…