您的位置:首页 > 其它

安卓修改开机动画

2014-07-23 15:25 501 查看
一、概述

为了在项目中对安卓系统进行定制化,需要将其开机动画进行修改,因此,上网搜了一堆原理教程,这里就根据自己的理解进行梳理,有任何错漏,欢迎指正。

二、开机动画原理

安卓系统完整的启动过程具体如下:

1. 启动BootLoader

2. 加载系统内核

3. 启动Init和其它重要守护进程

4. 启动Zygote进程

5. 启动Runtime进程,初始化Service Manager。启动SystemService

6. 启动HomeLaucher

7. 启动其它应用程序

这里我们要关注的是第3点,启动Init和其它重要守护进程。

在系统内核加载完成之后,系统启动第一个用户进程,即Init进程。Init进程一启动就根据init.rc和init.hardware.rc(hardware为具体硬件名称)脚本文件执行需要启动的命令及服务。

在init.rc启动服务过程中,直接启动了一个SurfaceFlinger服务。SurfaceFlinger服务用于管理安卓系统应用端所有的surface,每个应用相当于客户端,surfaceFlinger相当于服务端,客户端完成图形处理之后,请求SurfaceFlinger显示到屏幕上。

启动surfaceFlinger的过程中,调用了开机动画的应用程序bootanim,使得开机动画能够进行显示;当启动结束时,surfaceFlinger会请求bootanim退出,然后开机过程结束。

这里的启动过程就是如上所述的那样,下面看看源码是如何写的。

1、init.rc启动SurfaceFlinger服务

代码位置:\android42\device\softwinner\wing-common\init.rc(该源码为cubieboard2配套源码,下同)。

# Set this property so surfaceflinger is not started by system_init
setprop system_init.startsurfaceflinger 0

service surfaceflinger /system/bin/surfaceflinger
class main
user system
group graphics drmrpc
onrestart restart zygote


这部分代码设置了surfaceflinger在init进程中启动及启动surfaceflinger。具体细节如下:

1)设置surfaceflinger在init进程中启动

在android系统中核心的Service(如surfaceFlinger)都由ServiceManager管理,核心Service启动一般是在SystemServer来启动。而这里的setprop语句用于设置属性值,将system_init.startsurfaceflinger设置为0时,表示系统将在init进程中启动surfaceflinger,不需要再SystemServer中启动。

可参考SystemServer启动SurfaceFlinger服务的代码:

代码位置:\android42\frameworks\base\cmds\system_server\library\system_init.cpp

extern "C" status_t system_init()
{
…
char propBuf[PROPERTY_VALUE_MAX];
//获取init.rc中的system_init.startsurfaceflinger属性。
//若该属性为1,则启动SurfceFlinger服务。
//若为0,表示该服务已在init进程中启动。
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
…
}

2)Init.rc启动surfaceflinger

该部分脚本代码遵循Android Init Language规范,该规范可参考官网中http://www.kandroid.org/online-pdk/guide/bring_up.html的介绍,或者在android42\system\core\init\ReadMe.txt中。

这里定义了surfaceflinger为init进程中的一个服务及其相应的文件位置,并将其归为main类,在此类中,所有服务同时启动。在surfaceflinger服务重新启动时,重启zygote服务。

2、启动surfaceFlinger服务。

入口函数源码位于:

android42\frameworks\native\cmds\surfaceflinger\main_surfaceflinger.cpp

int main(int argc, char** argv) {
SurfaceFlinger::publishAndJoinThreadPool(true);
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
return 0;
}

该部分将SurfaceFlinger服务在ServiceManager中进行注册并启动。

在surfaceFlinger服务启动之后,它会调用startBootAnim()来启动开机动画。

代码位置:

android42\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

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

void SurfaceFlinger::bootFinished()
{
…
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
property_set("service.bootanim.exit", "1");
…
}

其中startBootAnim()通过ctl.start启动bootanim的应用程序。

在bootFinished()中通过service.bootanim.exit请求bootanim自动退出。

此外,在adb shell中,可通过命令“setprop ctl.start bootanim”启动开机动画;命令“setprop ctl.stop bootanim”停止开机动画。

3、运行bootanim应用程序。

具体bootanim应用程序的源码位于:

android42\frameworks\base\cmds\bootanimation\

包括:bootanimation_main.cpp(应用程序入口),BootAnimation.cpp(应用程序实现),BootAnimation.h(头文件)。

在bootanimation_main.cpp中,实现了与SurfaceFlinger的绑定并启动开机动画实现的应用程序。源代码如下:

int main(int argc, char** argv)
{
#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
#endif
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.nobootanimation", value, "0");
int noBootAnimation = atoi(value);
ALOGI_IF(noBootAnimation,  "boot animation disabled");
if (!noBootAnimation) {
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
// create the boot animation object
sp<BootAnimation> boot = new BootAnimation();
boot->playBootMusic("/system/media/boot.wav");
IPCThreadState::self()->joinThreadPool();
}
return 0;
}

在main函数中,首先获取init.rc/build.prop中debug.sf.nobootanimation的值是否为0。该值为0则执行开机动画程序,该值为1则不执行。默认情况下该文件中没有这个属性,在该函数中,当没有这个属性时,获取到的值将其设置为0。即系统是默认执行开机动画程序。

开机动画应用程序源码为BootAnimation.cpp,具体如下:

//定义用户自定义开机动画文件位置
#define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip"
#define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
#define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"

//线程启动初始化函数
status_t BootAnimation::readyToRun() {
…
//判断是否存在用户自定义开机动画文件,若存在,则将mAndroidAnimation设置为false
if ((encryptedAnimation &&
(access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE) == NO_ERROR)) ||
((access(USER_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)) ||
((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))) {
mAndroidAnimation = false;
}
…
}
//线程循环函数。
//若mAndroidAnimation为true,则调用android(),这是安卓系统默认的开机动画
//会根据/frameworks/base/core/res/assets/images/android-logo-mask.png,///frameworks/base/core/res/assets /images/android-logo-shine.png的两张图
//片,通过代码控制达到动画效果。
//若mAndroidAnimation为false,则显示用户自定义的动画。
bool BootAnimation::threadLoop()
{
bool r;
if (mAndroidAnimation) {
r = android();
} else {
r = movie();
}
}

具体开机动画控制的相关函数,可参考具体代码。

从代码中可以看出:为了显示自定义的开机动画效果,需要确保:

1)init.rc/build.prop中没有debug.sf.nobootanimation属性,或者该属性值为0。

2)/data/local/或者/system/media/文件夹中有bootanimation.zip。

4、bootanimation.zip说明。

此处对bootanimation.zip进行说明,里面的内容是:



注意:此处不能有上层文件夹。

其中,desc.txt的文本内容为

1280 720 40
p 0 0 part0
p 0 0 part1

第一行:数字的含义分别是屏幕宽度,屏幕长度,帧数(每秒多少帧);

第二行:第一项是标识符,p表示该行是该animation的一个part;

第二项是循环次数,1表示循环一次,0表示无限循环;

第三项是两次循环之间的间隔时间;

第四项是对应的目录名。

压缩是需要用存储的方式,否则程序无法读取内容。

1.windows使用winrar打包,选择ZIP 格式,压缩标准要选“储存”;

2. linux下,zip -0 -r ../bootanimation.zip ./*

linux命令使用-0 指定压缩等级为最低等级stored,即只归档不压缩,否则可能由于包格式问题引起动画显示为黑屏。

此外还应注意打包之后需要修改其运行权限,否则无法正常显示。

在shell中运行:chmod 777 bootanimation.zip

三、在CubieBoard2上修改步骤

参照《A10_android内容定制说明文档V2.1》上的说明,压缩相应的动画文件bootanimation.zip并进行权限修改,存放在\android42\device\softwinner\smfy-super3\media\目录下,进行系统编译,固件下载。

此外,也可以将bootanimation.zip存放在系统的/data/local/或者/system/media/文件夹中,无需编译即可实现开机动画效果。

四、参考文档

android从init到开机动画启动关闭流程一简易图

Android 启动过程详解

a​n​d​r​o​i​d​系​统​启​动​过​程

Android系统启动过程剖析

Android4.2.2SurfaceFlinger启动流程详解

学习SurfaceFlinger

《A10_android内容定制说明文档V2.1》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: