ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

RK3566 Android 11开机优化:屏蔽“正在启动”提示与视觉无缝衔接

RK3566 Android 11开机优化:屏蔽“正在启动”提示与视觉无缝衔接 1. 开机提示背后的系统逻辑与优化思路1.1 从一次实际项目需求说起前段时间接手了一个基于RK3566核心板的智能终端项目系统跑的是Android 11整机形态类似桌面安卓电脑配了8寸1280×800的LVDS屏幕4128GB存储组合一个USB 3.0加一个USB 2.0接口。硬件调试阶段一切顺利LVDS点亮、触摸校准、CH340串口通信都跑通了但到了整机交付前的体验验收环节客户提了一个很具体的要求开机过程中屏幕上那个“正在启动”的提示必须去掉换成他们自己的品牌Logo动画。这个需求听起来简单但实际动手才发现Android 11在RK3566/RK3568这类瑞芯微平台上开机流程涉及U-Boot、Kernel、Init、Zygote、SystemServer多个阶段每个阶段都有各自的显示逻辑。“正在启动”这个提示并不是某一个固定文件里的字符串而是系统在特定启动阶段由FallbackHome机制触发的默认界面。要彻底屏蔽它得先搞清楚它到底在哪个环节冒出来。这篇文章就是把我整个排查和修改过程完整记录下来包括设备树配置、FallbackHome机制分析、开机动画替换、以及最终验证的完整步骤。如果你手上有RK3566或RK3568的开发板跑的是Android 11也遇到了类似的开机界面定制需求这篇内容可以直接抄作业。1.2 为什么“正在启动”会出现在屏幕上Android系统的启动显示大致分三个阶段。第一阶段是U-Boot阶段这个阶段屏幕通常显示的是U-Boot的Logo或者黑屏取决于U-Boot有没有配置开机Logo。第二阶段是Kernel启动到Init阶段这个阶段会加载开机动画资源也就是bootanimation.zip。第三阶段是SystemServer启动完成后Launcher正式接管桌面之前的过渡阶段。“正在启动”这个提示实际上出现在第三阶段。具体来说当SystemServer启动完成但用户设置的Launcher还没有准备好或者没有被正确配置时系统会启动一个叫FallbackHome的临时Home应用。这个FallbackHome的界面就是一个简单的提示文字在中文语言环境下显示为“正在启动”英文环境下显示为“Starting Android”。注意FallbackHome不是bug它是Android系统的一个保护机制。当默认Launcher因为某些原因无法启动时FallbackHome会临时接管避免系统卡在黑屏状态。所以我们的目标不是删除FallbackHome而是让它在正常启动流程中不显示出来。1.3 整体优化方案的选型考量针对屏蔽“正在启动”提示这个需求市面上常见的做法有三种。第一种是直接修改FallbackHome的源码把界面改成透明或者直接删掉。第二种是修改系统配置让FallbackHome在启动时直接跳过显示。第三种是替换整个开机动画流程让bootanimation一直显示到Launcher起来为止。我最终选择的是组合方案修改FallbackHome的显示逻辑让它透明化同时延长bootanimation的显示时间确保从Kernel启动到Launcher接管之间没有视觉断层。这样做的好处是不破坏系统的FallbackHome保护机制即使Launcher启动失败系统仍然有兜底方案只是用户看不到那个提示界面而已。为什么不直接删掉FallbackHome因为在实际调试中我发现某些情况下Launcher的启动确实会延迟如果直接删掉FallbackHome系统会短暂黑屏体验反而更差。透明化处理既保留了保护机制又满足了客户对视觉连续性的要求。2. FallbackHome机制深度解析与修改实操2.1 FallbackHome在Android 11中的启动流程要改FallbackHome先得知道它是怎么被拉起来的。在Android 11的源码中FallbackHome的代码位于frameworks/base/services/core/java/com/android/server/am/目录下具体文件是FallbackHome.java。这个类继承自Activity但它的启动时机很特殊。系统启动时ActivityManagerService会检查当前用户是否已经设置了Home应用。如果用户没有设置或者设置的Home应用还没有完成初始化AMS就会启动FallbackHome作为临时Home。FallbackHome的onCreate方法里会注册一个广播接收器监听ACTION_USER_UNLOCKED和ACTION_PACKAGE_CHANGED等广播。当真正的Launcher准备好后FallbackHome会收到通知并调用finish()退出。在RK3566/RK3568的Android 11 SDK中FallbackHome的默认布局文件是fallback_home.xml里面就是一个居中的TextView显示的文字资源是android:string/startup_message中文环境下就是“正在启动”。2.2 定位FallbackHome源码与资源文件在瑞芯微的Android 11 SDK中FallbackHome的源码路径和AOSP基本一致但布局文件可能会被厂商定制。我拿到的SDK里FallbackHome的布局文件在frameworks/base/core/res/res/layout/fallback_home.xml内容大致如下LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent android:gravitycenter android:orientationvertical TextView android:idid/fallback_home_text android:layout_widthwrap_content android:layout_heightwrap_content android:textandroid:string/startup_message android:textSize24sp android:textColorandroid:color/white / /LinearLayout要确认你的SDK里具体路径可以用find命令搜索find frameworks/base -name fallback_home.xml 2/dev/null find frameworks/base -name FallbackHome.java 2/dev/null如果搜不到可能是厂商把FallbackHome的布局改到了其他位置或者直接用了代码动态创建View。这时候需要反编译framework-res.apk来确认。2.3 修改FallbackHome实现透明化处理我的修改思路很简单把FallbackHome的界面改成完全透明同时去掉文字显示。具体操作分两步。第一步修改布局文件。把fallback_home.xml改成FrameLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent android:backgroundandroid:color/transparent /FrameLayout第二步修改FallbackHome.java中的窗口属性。在onCreate方法里添加getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));这样FallbackHome启动后屏幕上不会显示任何内容也不会拦截触摸事件用户完全感知不到它的存在。实操心得修改FallbackHome.java后需要重新编译framework.jar。在RK3566/RK3568的Android 11 SDK中编译命令是make framework或者make -j8 framework。编译完成后生成的framework.jar在out/target/product/rk3566_r/目录下需要push到设备的/system/framework/目录。2.4 编译与验证FallbackHome修改编译framework.jar时有个坑要注意RK3566和RK3568的SDK默认可能开启了预编译优化直接make framework可能不会重新编译修改过的Java文件。我的做法是先执行make clean-framework清理再执行make framework。编译完成后用adb push到设备adb root adb remount adb push out/target/product/rk3566_r/system/framework/framework.jar /system/framework/ adb reboot重启后观察开机过程如果“正在启动”提示消失说明修改生效。如果还有可能是FallbackHome的布局被其他资源覆盖了需要检查framework-res.apk里的资源。3. 开机动画与启动流程的视觉衔接优化3.1 RK3568 U-Boot阶段的开机Logo配置屏蔽了FallbackHome的提示后新的问题出现了从U-Boot到Kernel再到bootanimation之间屏幕会有短暂的黑屏。客户要求整个开机过程视觉连续所以还得把U-Boot和Kernel阶段的显示也统一起来。RK3568的U-Boot阶段显示Logo需要在U-Boot的设备树中配置logo节点。具体是在u-boot/arch/arm/dts/rk3568-xxx.dts中添加logo { status okay; logo,uboot logo.bmp; logo,kernel logo_kernel.bmp; logo,mode center; };其中logo.bmp是U-Boot阶段显示的图片logo_kernel.bmp是Kernel启动阶段显示的图片。这两张图片需要放在u-boot/resource/目录下编译时会打包进resource.img。注意RK3568的U-Boot Logo图片格式要求是BMP分辨率不能超过屏幕分辨率颜色深度支持24位和32位。我试过用1280×800的BMP图片显示正常。3.2 Kernel阶段的开机Logo与bootanimation衔接Kernel启动阶段RK3568会通过logo_kernel.bmp显示开机Logo。这个Logo会一直显示到bootanimation启动。bootanimation的启动时机是在Init阶段由init.rc中的service bootanim触发。为了让视觉连续我把logo_kernel.bmp和bootanimation的第一帧做成同一张图。这样从Kernel Logo到bootanimation之间就没有视觉跳变。具体操作是准备一张1280×800的PNG图片作为bootanimation的第一帧。用工具把PNG转成BMP命名为logo_kernel.bmp放到U-Boot的resource目录。把PNG图片放入bootanimation.zip的part0目录作为第一帧。bootanimation.zip的结构如下bootanimation.zip ├── desc.txt ├── part0/ │ └── frame_000.png └── part1/ └── frame_001.pngdesc.txt的内容1280 800 30 p 1 0 part0 p 0 0 part1第一行表示分辨率1280×800帧率30fps。第二行表示part0播放1次后停止第三行表示part1循环播放。3.3 延长bootanimation显示时间确保无缝过渡默认情况下bootanimation会在SystemServer启动完成后退出。但FallbackHome透明化后Launcher启动可能需要额外时间如果bootanimation退出太早屏幕会短暂黑屏。我的做法是修改bootanimation的退出逻辑让它等到Launcher真正显示第一帧后再退出。具体是在frameworks/base/cmds/bootanimation/BootAnimation.cpp中修改checkExit()函数bool BootAnimation::checkExit() { if (mExitPending) { return true; } // 增加判断等待Launcher显示 if (mSystemReady !mLauncherReady) { return false; } return false; }同时需要在SystemServer中发送一个广播通知bootanimation Launcher已经准备好。这个修改涉及ActivityManagerService和BootAnimation的交互代码量较大如果不想改这么多还有一个更简单的办法在desc.txt中把part1的循环次数设为无限然后在Launcher启动后手动停止bootanimation。adb shell setprop service.bootanim.exit 1这个命令可以在Launcher的onCreate中调用确保bootanimation在Launcher显示后才退出。3.4 实测效果与参数调优记录经过上述修改我的RK3566开发板开机过程变成了U-Boot显示品牌Logo → Kernel显示同一张Logo → bootanimation播放动画 → Launcher显示桌面。整个过程没有“正在启动”提示也没有黑屏断层。实测数据从按下电源键到Launcher显示总耗时约18秒。其中U-Boot阶段2秒Kernel阶段3秒bootanimation阶段10秒Launcher启动3秒。相比修改前总时间没有明显增加但视觉体验提升很大。实操心得bootanimation的帧率不要设太高30fps足够设60fps会增加CPU负载反而拖慢启动。另外bootanimation.zip的压缩方式要用store模式不能用deflate否则系统解压会消耗额外时间。4. 常见问题排查与避坑指南4.1 FallbackHome修改后不生效的排查思路修改FallbackHome后最常见的问题是“改了没效果”。我遇到过几次排查下来通常是以下几个原因。第一framework.jar没有真正更新。用adb shell dumpsys package查看framework的版本号确认是否是新编译的。如果版本号没变说明push没成功或者设备没有重启。第二FallbackHome的布局被overlay覆盖。有些厂商会在device/rockchip/目录下放overlay资源覆盖了AOSP的默认布局。检查device/rockchip/rk3566/overlay/frameworks/base/core/res/res/layout/目录下有没有fallback_home.xml。第三FallbackHome的启动逻辑被修改。有些SDK会定制FallbackHome的启动条件比如在ActivityManagerService.java中直接跳过了FallbackHome的启动。这时候需要检查systemReady方法中的相关代码。4.2 开机动画不显示或显示异常的解决方法bootanimation不显示通常是因为desc.txt格式不对或者图片命名不规范。RK3568的bootanimation对图片命名有要求必须是frame_%05d.png格式比如frame_00000.png、frame_00001.png。如果命名不对bootanimation会直接跳过。另一个常见问题是bootanimation.zip的权限不对。在Android 11中bootanimation.zip需要放在/system/media/目录下权限是644所有者是root:root。可以用以下命令检查adb shell ls -l /system/media/bootanimation.zip如果权限不对用chmod 644修改。4.3 设备树配置错误的典型表现RK3568的设备树配置错误最典型的表现是屏幕不亮或者显示花屏。我在调试LVDS屏幕时遇到过原因是lvds节点的status没有设为okay或者>lvds { status okay; >gt911 { touchscreen-swapped-x-y; touchscreen-inverted-x; };这样触摸坐标就会自动旋转和屏幕显示方向一致。6. 个人实操体会与后续扩展整个项目做下来最大的体会是Android系统的开机流程虽然复杂但每个阶段的显示逻辑都有明确的入口和出口。只要找准了FallbackHome这个关键点屏蔽“正在启动”提示并不难。难的是保证整个开机过程的视觉连续性和系统稳定性这需要反复测试和调优。我在实际调试中还发现不同批次的RK3566核心板U-Boot的Logo显示可能有差异。有些批次的U-Boot默认不显示Logo需要在编译时加上CONFIG_ROCKCHIP_LOGO配置。这个坑我踩过一次后来在u-boot/configs/rk3566_defconfig中加上了这个配置才解决。后续如果还要进一步优化我打算试试把bootanimation换成视频格式用bootvideo替代bootanimation这样动画效果会更流畅。另外Launcher的启动速度还有优化空间可以通过裁剪不必要的系统应用来缩短启动时间。最后分享一个小技巧在调试开机流程时可以用adb shell dmesg | grep -i logo\|bootanim\|fallback实时查看相关日志快速定位问题。这个命令帮我省了不少排查时间。
返回列表