首次开机android.intent.action.BOOT_COMPLETED开机广播发送慢的问题
1. 背景
做过android开发的同学相信一定做个这种逻辑:app接收BOOT_COMPLETED开机广播,自启动,或者收到广播做一些事情。目前在我们的项目上遇到首次开机,BOOT_COMPLETED开机广播发送慢的问题。接下来分享记录下如何定位这类问题。
2. 分析过程
01-01 08:00:33.689247 1014 1840 I wm_create_activity:[0,42774215,7,com.android.launcher/.activity.LauncherActivity,android.intent.action.MAIN,NULL,NULL,268435712]
launcer界面的创建时间点为08:00:33
01-01 08:00:39.384523 1014 1855 I ActivityManager: Posting BOOT_COMPLETED user #0
系统发送开机广播的时间为08:00:39
中间有6秒多的间隔,需要看看开机广播发送慢的问题。
1.第一次开机,boot_completed广播之前,会先执行PreBoot 耗时6s,这是google原生行为。
行 24354: 01-01 08:00:33.293553 1014 1288 I uc_finish_user_unlocked: 0
行 24429: 01-01 08:00:33.302932 1014 1288 I PreBootBroadcaster: Pre-boot of {com.android.documentsui/com.android.documentsui.PreBootReceiver} for user 0
行 25647: 01-01 08:00:33.659771 1014 2704 I PreBootBroadcaster: Pre-boot of {com.android.managedprovisioning/com.android.managedprovisioning.ota.PreBootListener} for user 0
行 27224: 01-01 08:00:34.296557 1014 2907 I PreBootBroadcaster: Pre-boot of {com.android.providers.contacts/com.android.providers.contacts.ContactsUpgradeReceiver} for user 0
行 33427: 01-01 08:00:37.224144 1014 1856 I PreBootBroadcaster: Pre-boot of {com.android.providers.media.module/com.android.providers.media.MediaUpgradeReceiver} for user 0
行 37494: 01-01 08:00:39.384308 1014 1855 I uc_finish_user_unlocked_completed: 0
- 后面重启,不会有preboot动作,正常。
行 68220: 11-01 08:00:18.937687 960 1142 I uc_finish_user_unlocked: 0
行 68294: 11-01 08:00:18.943890 960 1142 I uc_finish_user_unlocked_completed: 0
行 115214: 11-01 08:01:17.388510 969 1098 I uc_finish_user_unlocked: 0
行 115407: 11-01 08:01:17.482497 969 1098 I uc_finish_user_unlocked_completed: 0
/*** Step from {@link UserState#STATE_RUNNING_UNLOCKING} to* {@link UserState#STATE_RUNNING_UNLOCKED}.*/void finishUserUnlocked(final UserState uss) {final int userId = uss.mHandle.getIdentifier();EventLog.writeEvent(EventLogTags.UC_FINISH_USER_UNLOCKED, userId);// Only keep marching forward if user is actually unlockedif (!StorageManager.isUserKeyUnlocked(userId)) return;synchronized (mLock) {// Bail if we ended up with a stale userif (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;// Do not proceed if unexpected stateif (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {return;}}mInjector.getUserManagerInternal().setUserState(userId, uss.state);uss.mUnlockProgress.finish();// Get unaware persistent apps running and start any unaware providers// in already-running apps that are partially awareif (userId == UserHandle.USER_SYSTEM) {mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);}mInjector.installEncryptionUnawareProviders(userId);// Dispatch unlocked to external appsfinal Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);unlockedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,Binder.getCallingUid(), Binder.getCallingPid(), userId);if (getUserInfo(userId).isManagedProfile()) {UserInfo parent = mInjector.getUserManager().getProfileParent(userId);if (parent != null) {final Intent profileUnlockedIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));profileUnlockedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY| Intent.FLAG_RECEIVER_FOREGROUND);mInjector.broadcastIntent(profileUnlockedIntent,null, null, 0, null, null, null, AppOpsManager.OP_NONE,null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),Binder.getCallingPid(), parent.id);}}// Send PRE_BOOT broadcasts if user fingerprint changed; we// purposefully block sending BOOT_COMPLETED until after all// PRE_BOOT receivers are finished to avoid ANR'ing appsfinal UserInfo info = getUserInfo(userId);if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {// Suppress double notifications for managed profiles that// were unlocked automatically as part of their parent user// being unlocked.final boolean quiet;if (info.isManagedProfile()) {quiet = !uss.tokenProvided|| !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);} else {quiet = false;}mInjector.sendPreBootBroadcast(userId, quiet,() -> finishUserUnlockedCompleted(uss));} else {finishUserUnlockedCompleted(uss);}}
关键log记录:
01-01 08:00:32.310344 1014 1265 D ActivityManager: Started unlocking user 0
01-01 08:00:32.310389 1014 1265 D ActivityManager: Unlocking user 0 progress 0
01-01 08:00:32.310526 1014 1265 D ActivityManager: Unlocking user 0 progress 5
01-01 08:00:33.245283 1014 1261 I ActivityManager: User 0 state changed from RUNNING_LOCKED to RUNNING_UNLOCKING
01-01 08:00:33.246592 1014 1261 D ActivityManager: Unlocking user 0 progress 20
unlockUserCleared
finishUserUnlocking
finishUserUnlocked
finishUserUnlockedCompleted
相关文章:
首次开机android.intent.action.BOOT_COMPLETED开机广播发送慢的问题
1. 背景 做过android开发的同学相信一定做个这种逻辑:app接收BOOT_COMPLETED开机广播,自启动,或者收到广播做一些事情。目前在我们的项目上遇到首次开机,BOOT_COMPLETED开机广播发送慢的问题。接下来分享记录下如何定位这类问题。 2. 分析过…...

通信工程学习:什么是OLT光线路终端
OLT:光线路终端 OLT(Optical Line Terminal,光线路终端)是光纤通信系统中的核心局端设备,特别是在无源光网络(Passive Optical Network, PON)架构中扮演着至关重要的角色。以下是关于OLT光线路终…...
Unity的Button组件进行扩展
废话不多说,在Untiy中,如果想要对Button等组件进行扩展的话,那么不仅仅只需要将新增的属性设置为public或者增加SerializeField字段就行了的,同时需要对Inspector的GUI面板进行修改,以下直接展示代码: usi…...

前端vue-插值表达式和v-html的区别
创建vue实例的时候,可以有两种形式。 1.let appnew Vue({}) 2 const appnew Vue({}) 3 el是挂载点,是上面div的id值 4 data中的值可以展示在上面div中 5 v-html标签里面如果有内容,则我们的新内容会把标签里面的内容覆盖掉...

【开发心得】筑梦上海:项目风云录(4)
不知不觉已经写到了第4篇,天下大事,必作于细。 其实项目管理也是如此,成功都在细节之处。自从博士离开以后,项目逐步开始进入了正常轨道。来来回回的30多人,也不能一一列举的记流水账。 目录 会海和MSN 小娇往事 …...
el-table使用el-switch选择器没效果
出现问题的代码: 0表示启用,1表示禁用,发现页面根本没有效果,百思不得其解,查阅资料,恍然大悟。 <el-table :data"userList" stripe border style"width: 100%" height"500"><…...
libserailport交叉编译适配说明
1:libserialport简介 github路径 自己的gitee路径 libserialport 是一个跨平台的串口通信库,由 sigrok 项目开发。它简洁、易用,并且支持多种操作系统。 libserialport 支持阻塞和非阻塞模式,可以根据你的需求选择适当的模式。阻…...
C语言中的一些小知识(二)
一、"%"运算符两侧只能是整数 在C语言中,% 运算符称为模运算符或取余运算符,它用于计算两个整数相除后的余数。当使用 % 运算符时,操作数必须是整数类型(包括 char、int、long 等)。 语法 remainder div…...
使用 Go 语言实现简单聊天系统
在互联网时代,聊天系统是常见的应用场景之一。无论是即时通讯、在线客服还是多人游戏中的消息系统,聊天功能的实现都是必不可少的。本文将使用 Go 语言,结合 WebSocket 来构建一个简单的多人聊天室系统。 一、项目结构 首先,我们…...

用友U8二次开发工具KK-FULL-*****-EFWeb使用方法
1、安装: 下一步,下一步即可。弹出黑框不要关闭,让其自动执行并关闭。 2、服务配置: 输入服务器IP地址,选择U8数据源,输入U8用户名及账号,U8登录日期勾选系统日期。测试参数有效性,提示测试通过…...

【经验帖】脏读和不可重复读的概念及影响
脏读和不可重复读是数据库事务并发执行时可能出现的两种数据一致性问题,它们对数据的一致性和完整性有着显著的影响。以下是脏读和不可重复读的具体影响: 脏读的影响 脏读发生在一个事务读取了另一个事务未提交的数据时。由于这些数据尚未被提交&#x…...

MTK zephyr平台:USB升级、枚举流程
一、USB升级流程 通过代码及log分析,当前平台升级过程在PL阶段进行 USB download相关代码 mtk/modules/hal/boot/preloader/platform/flashc/ mtk/modules/hal/boot/preloader/platform/board_name/flash/ mtk/modules/hal/boot/preloader/platform/board_name/src/drive…...

golang操作mysql利器-gorm
1、傻瓜示例 GORM通过将数据库表中的数据映射到面向对象的模型中,简化了数据库操作,使得开发者可以很方便的使用代码来操作数据库,而无需编写SQL语句。 目前有个mysql表:miniprogram_orders,其存储了所有用户对应的订…...
09 Shell Scriptfor循环结构语句
Shell Scriptfor循环结构语句 一、Shell FOR循环语句概述 属于shell的符合语句 可以看出帮助信息给出了两种语法 [rootlocalhost ~]# help for for: for NAME [in WORDS ... ] ; do COMMANDS; doneExecute commands for each member in a list.The for loop executes…...

【Java】并发集合
并发集合(java.util.concurrent) 一、List CopyOnWriteArrayList(ReentrantLock实现线程安全) (1)并发修改(写操作)时保证线程安全: 通过ReentrantLock实现多个线程并…...

活动邀请|景联文科技与您相约华为全联接大会2024
2024年9月19-21日,第九届华为全联接大会(简称:HUAWEICONNECT2024)将在上海世博展览馆和上海世博中心举办。 作为华为的旗舰盛会,本次大会以“共赢行业智能化”为主题将邀请思想领袖、商业精英、技术专家、合作伙伴、开发者等业界同仁…...

周边游|基于springBoot的周边游平台设计与实现(附项目源码+论文+数据库)
私信或留言即免费送开题报告和任务书(可指定任意题目) 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 在如今社会上,关于信息上面的处理,没有任…...
【编程基础知识】mysql是怎样执行一条sql语句的,涉及到哪些环节步骤是,mysql的整体体系结构是啥样的,有哪些组件
一、步骤 MySQL执行一条SQL语句的过程涉及多个环节和步骤。以下是这一过程的概述: 客户端连接:客户端通过连接器(Connector)向MySQL服务器发起连接请求。身份验证:连接器对用户身份进行验证,确保用户有权…...

如何上传tauri项目到csdn gitcode
如何上传tauri项目到csdn gitcode 首先保证项目目录有.gitignore,避免不必要的文件上传分享。 gitignore文件 # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log*node_modules dist dist-ssr *.local# Editor …...

【速成Redis】02 Redis 五大基本数据类型常用命令
前言: 上一节课,我们对redis进行了初步了解,和安装好了redis。【速成Redis】01 Redis简介及windows上如何安装redishttps://blog.csdn.net/weixin_71246590/article/details/142319358?spm1001.2014.3001.5501 该篇博客,我们正…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...