1、概述
Android的开机启动流程大致可以分为三个阶段,第一阶段为kernel logo图片显示(本文不做分析);第二阶段为Android logo图片显示,第三阶段为Android开机动画。
2、修改启动log
2.1 init.cpp
int main(int argc, char** argv) {
......
queue_builtin_action(console_init_action, "console_init");
......
}
2.2 图片logo显示
默认情况下,系统会显示Android字样的一张图片;代码如下:
static int console_init_action(int nargs, char **args)
{
int fd;
char tmp[PROP_VALUE_MAX];
if (console[0]) {
snprintf(tmp, sizeof(tmp), "/dev/%s", console);
console_name = strdup(tmp);
}
fd = open(console_name, O_RDWR);
if (fd >= 0)
have_console = 1;
close(fd);
if( load_565rle_image(INIT_IMAGE_FILE) ) { //如有自定义logo则显示自定义;否则默认显示Android字样
fd = open("/dev/tty0", O_WRONLY);
if (fd >= 0) {
const char *msg;
msg = "\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n" // console is 40 cols x 30 lines
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
" A N D R O I D ";
write(fd, msg, strlen(msg));
close(fd);
}
}
return 0;
}
初始化控制台。init进程在启动的时候,会解析内核的启动参数(保存在文件/proc/cmdline中)。如果发现内核的启动参数中包含有了一个名称为“androidboot.console”的属性,那么就会将这个属性的值保存在字符数组console中。这样我们就可以通过设备文件/dev/<console>
来访问系统的控制台。如果内核的启动参数没有包含名称为“androidboot.console”的属性,那么默认就通过设备文件/dev/console来访问系统的控制台。如果能够成功地打开设备文件/dev/或者/dev/console,那么就说明系统支持访问控制台,因此,全局变量have_console的就会被设置为1。
显示第二个开机画面。显示第二个开机画面是通过调用函数load_565rle_image来实现的。在调用函数load_565rle_image的时候,指定的开机画面文件为INIT_IMAGE_FILE。INIT_IMAGE_FILE是一个宏,定义在system/core/init/init.h文件中
2.3 制作并显示自定义图片
1,准备一张png图片,图片大小随意,但是必须裁剪成和LCD尺寸大小一样,本实验的LCD尺寸是480x272,所以选了一张480x272大小的png图片
2,将图片转换为raw格式,使用linux下的imagemagick自带的convert命令,进行raw格式转换,命令为:
Convert -depth 8 honeycomb_480x272.png rgb:honeycomb_480x272.raw
注:如果当前系统没有安装,可以执行下面的命令安装:
sudo apt-get install imagemagick
- 将raw格式转化为rle文件需要用到android编译后的rgb2565工具,在android/out/host/linux-x86/bin目录下(android为当前源码所在目录),转换命令如下:
./out/host/linux-x86/bin/rgb2565 -rle <honeycomb_480x272.raw >honeycomb_480x272.rle
4,将honeycomb_480x272.rle拷贝至文件系统的根目录下
修改:
#define INIT_IMAGE_FILE "/initlogo.rle"
改为:
#define INIT_IMAGE_FILE "/honeycomb_480x272.rle"
3、修改开机动画:
3.1 开机动画实际就是多张图片循环播放,所以需要大家去制作多张能循环播放的图片,并且图片连续起来能有动画的效果
3.2 bootanimation.zip中内容格式为
bootanimation.zip
|-- desc.txt
|-- part0
`-- part1
其中desc.txt为描述文件格式如下:
480 427 30 宽 高 帧数
p 1 0 part0 标志符 循环次数 阶段切换间隔时间 对应目录名
p 0 0 part1 标志符 循环次数 阶段切换间隔时间 对应目录名
注意:在p 0 0 part1结束后,回车加入换行符;否则解析时,无法解析第三行
desc.txt为描述文件解析代码如下:
// Parse the description file
for (;;) {
const char* endl = strstr(s, "\n");
if (endl == NULL) break;
String8 line(s, endl - s);
const char* l = line.string();
int fps, width, height, count, pause;
char path[ANIM_ENTRY_NAME_MAX];
char color[7] = "000000"; // default to black if unspecified
char pathType;
if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
// ALOGD("> w=%d, h=%d, fps=%d", width, height, fps);
animation.width = width;
animation.height = height;
animation.fps = fps;
}
else if (sscanf(l, "%c %d %d %s #%6s", &pathType, &count, &pause, path, color) >= 4) {
// ALOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s", pathType, count, pause, path, color);
Animation::Part part;
part.playUntilComplete = pathType == 'c';
part.count = count;
part.pause = pause;
part.path = path;
part.audioFile = NULL;
if (!parseColor(color, part.backgroundColor)) {
ALOGE("> invalid color '#%s'", color);
part.backgroundColor[0] = 0.0f;
part.backgroundColor[1] = 0.0f;
part.backgroundColor[2] = 0.0f;
}
animation.parts.add(part);
}
s = ++endl;
}
3.3 重新压缩
linux下的压缩方法为:(加入-0的意思是indicates no compression (store all files))
zip -0 -r ../bootanimation.zip *
5,将bootanimation.zip放到开发板的文件系统/system/media/目录下即可