跳转至

启动动画

正如在上一章讨论启动 logo 时所解释的,Android 的 LCD 在启动过程中经历四个阶段。其中之一就是启动动画。以下是 2.3/Gingerbread init.rc 中的相关条目(4.2/Jelly Bean 中的条目几乎相同):

service bootanim /system/bin/bootanimation
    user graphics
    group graphics
    disabled
    oneshot

请注意,这个服务被标记为 disabled。因此,init 实际上不会立即启动它。相反,它必须在其他地方被明确启动。在这种情况下,是由 Surface Flinger 在完成自己的初始化后,通过设置 ctl.start 全局属性来实际启动启动动画。以下是 2.3/Gingerbread 的 frameworks/base/services/surfaceflinger/SurfaceFlinger.cppSurfaceFlinger::readyToRun() 函数的相关代码:

// start boot animation
property_set("ctl.start", "bootanim");

4.2/Jelly Bean 的 frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp 中的代码做的事情实质相同:

void SurfaceFlinger::startBootAnim() {
    // start boot animation
    property_set("service.bootanim.exit", "0");
    property_set("ctl.start", "bootanim");
}
...
status_t SurfaceFlinger::readyToRun()
{
...
    // start boot animation
    startBootAnim();
    return NO_ERROR;
}
...

鉴于 Surface Flinger 是最早启动的系统服务之一(如果不是最早的话),启动动画最终会在系统关键部分初始化时持续显示。通常,它只会在手机主屏幕最终出现时才停止。我们稍后会看看启动动画过程中发生的一些事情。

正如你在前面的 init.rc 片段中看到的,bootanim 服务对应的是 bootanimation 二进制文件。后者的源码在 frameworks/base/cmds/bootanimation/,如果你深入研究,你会发现这个工具直接通过 Binder 与 Surface Flinger 通信以渲染其动画;因此,Surface Flinger 需要在动画开始之前就已运行。图 7-1 展示了 bootanimation 显示的默认 Android 启动动画,其中带有投射在 Android logo 上的移动光线效果。

图 7-1. 默认启动动画

bootanimation 实际上有两种操作模式。在一种模式下,它使用 frameworks/base/core/res/assets/images/ 中的图像创建默认的 Android logo 启动动画。最好不要尝试通过修改这些文件来修改启动动画。相反,通过提供 /data/local/bootanimation.zip/system/media/bootanimation.zip,你将强制 bootanimation 进入另一种操作模式——使用其中一个 ZIP 文件的内容来渲染启动动画。尽管一本书不是展示运行动画的理想媒介,但值得花一些时间来了解如何做到这一点。

bootanimation.zip

bootanimation.zip 是一个常规的未压缩 ZIP 文件,其顶层目录中至少包含一个 desc.txt 文件,以及包含 PNG 文件的一些目录。后者根据 desc.txt 文件中的规则按顺序进行动画处理。请注意,bootanimation 不支持 PNG 以外的文件。以下是 desc.txt 文件的语义规范:

<width> <height> <fps>
p <count> <pause> <path>
p <count> <pause> <path>

请注意,该文件的格式非常简单,不允许任何多余的内容。所以请严格遵循上述语义。第一行表示动画的宽度、高度和帧率(每秒帧数)。每个后续的行都是动画的一个部分。对于每个部分,你必须提供该部分播放的次数(count)、每次播放后暂停的帧数(pause)以及该部分动画所在目录的路径(path)。各部分按它们在 desc.txt 中出现的顺序播放。

每个动画部分(以及因此相关的目录)由多个 PNG 文件组成,文件名是用作该帧在完整序列中序列号的字符串。例如,文件可以命名为 001.png、002.png、003.png 等。如果 count 设置为 0,该部分将循环播放,直到系统完成启动且启动器启动。通常,初始部分的 count 可能是 1,而最后一部分的 count 通常为 0,这样它会继续播放直到启动完成。

创建你自己的启动动画的最佳方式是查看他人创建的现有 bootanimation.zip 文件。如果你用你喜欢的搜索引擎搜索那个文件名,应该能相对容易地找到一些例子。例如,看看 CyanogenMod 第三方 Android 发行版创建的一些最新启动动画。

再次强调,确保你创建的 ZIP 文件没有被压缩。否则它将无法工作。请查看 zip 命令的手册页面——特别是 -0 标志。

禁用启动动画

如果你不想要启动动画,也可以完全禁用它。只需在 init.rc 中使用 setprop 命令将 debug.sf.nobootanimation 设置为 1:

setprop debug.sf.nobootanimation 1

在这种情况下,在启动 logo 显示之后,屏幕会在某个时候变黑,并保持黑屏,直到启动器应用显示主屏幕。