openharmony bootanimation

本文深入剖析了鸿蒙系统中的开机动画实现过程,从准备display、解析动画文件到画到屏幕的三个关键步骤。首先通过WindowManager初始化并获取显示屏信息,然后解析bootanimation的.raw文件,最后启动任务并创建窗口将动画绘制到屏幕上。这一流程展示了鸿蒙系统图形子系统的运作机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、开始

 

        bootanimation 是openharmony开机启动动画,也是openharmony图形子系统的一个比较不错的入口点,之前对基础和框架有个大概了解,这章用这个实例做一个把整个流程过一遍。它是一个service,在开机加载service是启动,下面是graphic.rc

service vsync_server /system/bin/vsync_server
    class weston
    disabled
    seclabel u:r:wms_service:s0

service bootanimation /system/bin/bootanimation
    class weston
    disabled
    oneshot

on weston_start
    start bootanimation

 如下为代码

int main(int argc, const char *argv[])
{
    const auto &wmi = WindowManager::GetInstance();
    auto wret = wmi->Init();
    if (wret != WM_OK) {
        LOG("WindowManager::Init() return %{public}s", WMErrorStr(wret).c_str());
        return 1;
    }

    std::vector<struct WMDisplayInfo> displays;
    wret = wmi->GetDisplays(displays);
    if (wret != WM_OK) {
        LOG("WindowManager::GetDisplays() return %{public}s", WMErrorStr(wret).c_str());
        return 1;
    }

    if (displays.size() == 0) {
        LOG("no display, cannot continue");
        return 1;
    }

    int64_t start = GetNowTime();
    if (RawParser::GetInstance()->Parse(displays[0].width, displays[0].height)) {
        return -1;
    }
    LOG("time: %{public}" PRIu64 "", GetNowTime() - start);

    Main m;

    auto runner = AppExecFwk::EventRunner::Create(false);
    auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
    handler->PostTask(std::bind(&Main::Init, &m, displays[0].width, displays[0].height));
    runner->Run();
    return 0;
}

大致可以分为三个步骤,

  • 准备display
  • 解析动画文件
  • 画到屏幕

我们按照这三步详细解析一下

2、准备display 

    const auto &wmi = WindowManager::GetInstance();
    auto wret = wmi->Init();
    if (wret != WM_OK) {
        LOG("WindowManager::Init() return %{public}s", WMErrorStr(wret).c_str());
        return 1;
    }

    std::vector<struct WMDisplayInfo> displays;
    wret = wmi->GetDisplays(displays);
    if (wret != WM_OK) {
        LOG("WindowManager::GetDisplays() return %{public}s", WMErrorStr(wret).c_str());
        return 1;
    }

 

3、解析开机动画

         鸿蒙开发者喜欢单例,这个开机动画文件解析真没有必要用单例

    if (RawParser::GetInstance()->Parse(displays[0].width, displays[0].height)) {
        return -1;
    }

        对bootanimation的ss << "/system/etc/bootanimation-" << width << "x" << height << ".raw";文件解析,放进std::vector<struct ZlibInfo> infos;中

4、画到屏幕

4.1 启动任务

    Main m;

    auto runner = AppExecFwk::EventRunner::Create(false);
    auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
    handler->PostTask(std::bind(&Main::Init, &m, displays[0].width, displays[0].height));
    runner->Run();

        这个主要启动一个任务,定时刷新页面,接下来一起看看怎么画的

4.2 创建窗口

    const auto &wmi = WindowManager::GetInstance();
    auto option = WindowOption::Get();
    option->SetWindowType(WINDOW_TYPE_NORMAL);
    option->SetWidth(width);
    option->SetHeight(height);
    option->SetX(0);
    option->SetY(0);

    auto wret = wmi->CreateWindow(window, option);

         WindowManager:窗口管理模块,包括窗口创建、显示隐藏、合成等处理,标准系统Windows使用WindowManagerImpl实现的,看一下客户端流程

<think>我们正在处理一个关于RK3588设备卡在开机动画的问题。根据引用资料,我们可以知道RK3588平台的开机动画通常是通过将bootanimation.zip文件放置在/system/media/目录下来实现的(引用[1])。此外,引用[3]提到在iTop3588平台上移植OpenHarmony时,需要确保uboot logo、kernel logo和开机动画的正常显示。 用户的问题:设备卡在开机动画,说明系统可能无法正常启动到桌面,而是停留在开机动画阶段。这可能是由于开机动画本身的问题,也可能是系统启动过程中其他环节的问题。 解决方案思路: 1. **检查开机动画文件**:首先确认bootanimation.zip文件是否正确。如果文件损坏或者格式不正确,可能导致动画无法正常播放,从而卡住。 2. **检查系统启动流程**:在显示开机动画之后,系统应该继续启动服务并进入桌面。如果系统服务启动失败,也可能导致卡在开机动画。 具体步骤: ### 1. 检查开机动画文件 - 确保`bootanimation.zip`文件存在于`/system/media/`目录下(引用[1])。 - 验证该文件的权限是否正确(通常为644,即rw-r--r--)。 - 检查文件内容:开机动画文件通常包含一个`desc.txt`文件和若干图片文件夹。我们可以尝试解压这个文件,检查其结构是否正确。 如果无法进入系统,可以通过以下方式检查: - 使用ADB连接设备(如果设备开启了ADB调试)。在卡在开机动画时,尝试使用`adb shell`进入设备,然后检查文件。 - 如果ADB无法连接,可能需要进入恢复模式(Recovery)或使用串口调试。 ### 2. 替换或移除开机动画 - 如果怀疑是开机动画文件的问题,可以尝试替换为一个已知良好的开机动画文件,或者移除开机动画文件(移除后系统将使用默认的Android开机动画,即显示“Android”字样)。 - 移除方法:在能够访问设备文件系统的情况下(如通过恢复模式),删除`/system/media/bootanimation.zip`文件。 ### 3. 检查系统启动日志 - 通过串口调试或ADB获取系统日志(logcat)和内核日志(dmesg),分析卡在开机动画时的错误信息。 - 查看日志中是否有明显的服务启动失败或异常。 ### 4. 检查文件系统 - 有时文件系统损坏也会导致启动问题。可以尝试在恢复模式下执行文件系统检查(fsck)。 ### 5. 恢复出厂设置或重新烧录系统 - 如果以上方法无效,可以考虑恢复出厂设置(在恢复模式下执行wipe data/factory reset)。注意:这会清除用户数据。 - 如果问题依旧,可能需要重新烧录系统(引用[4]提到使用balenaEtcher烧录系统镜像)。 ### 6. 硬件问题 - 在极少数情况下,可能是硬件问题(如内存不足或存储损坏)导致。需要检查硬件状态。 根据引用[5],在RK3588平台上,系统启动时间被优化,要求上电后3秒内出现开机画面。如果卡在开机动画,可能是启动过程中某个环节超时或失败。 ## 相关问题 §§相关问题§§ 1. 如何制作RK3588平台的开机动画? 2. 如何通过串口调试RK3588设备? 3. RK3588设备启动流程是怎样的? 4. 如何重新烧录RK3588设备的系统?</think>### RK3588设备卡在开机动画的解决方案 #### **问题原因分析** 当RK3588设备卡在开机动画时,通常由以下原因导致: 1. **开机动画文件损坏**:`bootanimation.zip`格式错误或内容异常(引用[1])。 2. **系统服务启动失败**:关键服务(如显示服务、系统UI)未正常加载。 3. **文件系统权限问题**:动画文件权限配置错误或存储介质损坏。 4. **内核/UBOOT异常**:显示驱动或帧缓冲初始化失败(引用[3][5])。 --- #### **解决方案步骤** ##### **1. 检查开机动画文件** ```bash # 通过ADB检查文件完整性 adb shell ls -l /system/media/bootanimation.zip # 确认文件存在 adb shell unzip -t /system/media/bootanimation.zip # 测试ZIP完整性 # 替换默认动画(紧急恢复) adb push new_bootanimation.zip /system/media/ adb shell chmod 644 /system/media/bootanimation.zip ``` - 若文件损坏,从原厂固件提取备份文件替换(引用[1])。 ##### **2. 检查系统日志** ```bash adb logcat | grep "BootAnimation" # 过滤动画进程日志 adb logcat | grep "SurfaceFlinger" # 检查显示服务 dmesg | grep "fb" # 检查帧缓冲驱动 ``` - 关键报错示例: - `BootAnimation exit timeout` → 动画渲染超时 - `SurfaceFlinger failed to start` → 显示服务崩溃 ##### **3. 验证文件系统** ```bash adb shell df -h /system # 检查/system分区空间 adb shell fsck /dev/block/mmcblk0p2 # 检查文件系统错误 ``` - 若`/system`空间不足,删除冗余文件(如旧日志)。 ##### **4. 内核级调试(需串口)** ```text # 串口连接后查看UBOOT日志 => printenv bootargs # 检查启动参数 => bdinfo # 查看内存映射 ``` - 确认`CONFIG_FRAMEBUFFER_CONSOLE=y`已启用(引用[3][5])。 ##### **5. 恢复出厂固件** - 使用balenaEtcher重新烧录官方镜像(引用[4]): 1. 下载适配RK3588的固件(如OpenHarmony或Android)。 2. TF卡烧录后插入设备强制刷机。 --- #### **预防措施** 1. **开机动画制作规范**: - 压缩格式:`store`模式(无压缩) - 分辨率匹配屏幕(如RK3588常支持4K) - 测试命令:`bootanimation`工具预览 2. **系统优化**: - 禁用非必要服务以加速启动(引用[5]) - 启用内核帧缓冲早期初始化(`earlycon`参数) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值