android 关机 流程_Android 9.0 开关机动画流程分析

Android开机动画流程的启动主要是在Surfaseflinger里面完成的,具体代码如下:

/frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp

32 bool StartPropertySetThread::threadLoop() {

33 // Set property service.sf.present_timestamp, consumer need check its readiness

34 property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");

35 // Clear BootAnimation exit flag

36 property_set("service.bootanim.exit", "0");

37 // Start BootAnimation if not started

38 property_set("ctl.start", "bootanim");

通过property_set("ctl.start", "bootanim");启动bootanim服务,启动服务的过程不做详细介绍,可以参考链接:

https://blog.csdn.net/zcyxiaxi/article/details/79159094

bootanim服务会启动开机动画的二进制执行文件,代码目录位于

/frameworks/base/cmds/bootanimation/bootanim.rc

1 service bootanim /system/bin/bootanimation

2 class core animation

3 user graphics

4 group graphics audio

5 disabled

6 oneshot

7 writepid /dev/stune/top-app/tasks

主要执行代码在/frameworks/base/cmds/bootanimation/BootAnimation.cpp文件中。

bool BootAnimation::threadLoop()

358  {

359   bool r;

360   // We have no bootanimation file, so we use the stock android logo

361   // animation.

362   if (mZipFileName.isEmpty()) {

363   r = android();

364   } else {

365   r = movie();

366   }

该方法判断mZipFileName内容是否为空,如果为空的话,就会执行android()方法走原生开机动画流程,原生开机动画是通过在界面上加载字符的方式实现的, 如果不为空的话就会走如下流程:

bool BootAnimation::movie()

817 {

818 Animation* animation = loadAnimation(mZipFileName);

..........

playAnimation(*animation);

.........

881 releaseAnimation(animation);

882

883 if (clockFontInitialized) {

884 glDeleteTextures(1, &animation->clockFont.texture.name);

885 }

886

887 return false;

888 }

先通过loadAnimation(mZipFileName)加载开机动画资源,然后playAnimation(*animation);播放开机动画,播放完以后通过releaseAnimation(animation);释放资源。

loadAnimation方法主要是传递资源路径,然后调用parseAnimationDesc方法处理动画资源,内容如下:

648 bool BootAnimation::parseAnimationDesc(Animation& animation)

649 {

650 String8 desString;

651

652 if (!readFile(animation.zip, "desc.txt", desString)) {//读取zip格式中的desc.txt内容并将值放到desString中,如果读取失败直接返回false。

653 return false;

654 }

655 char const* s = desString.string();

656

657 // Parse the description file

658 for (;;) {//for循环用来按行去读desc.txt里面的内容。

659 const char* endl = strstr(s, "\n");//搜索s字符串里面的话换行符,如果没有换行符的话直接返回NULL,搜索到换行符以后将返回换行符开始到字符串结尾的内容。

660 if (endl == NULL) break;

661 String8 line(s, endl - s);

662 const char* l = line.string();

663 int fps = 0;

664 int width = 0;

665 int height = 0;

666 int count = 0;

667 int pause = 0;

668 char path[ANIM_ENTRY_NAME_MAX];

669 char color[7] = "000000"; // default to black if unspecified

670 char clockPos1[TEXT_POS_LEN_MAX + 1] = "";

671 char clockPos2[TEXT_POS_LEN_MAX + 1] = "";

672 //将资源文件内读到的配置文件赋值到animation中。

673 char pathType;

674 if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {

675 // ALOGD("> w=%d, h=%d, fps=%d", width, height, fps);

676 animation.width = width;

677 animation.height = height;

678 animation.fps = fps;

679 } else if (sscanf(l, " %c %d %d %s #%6s %16s %16s",

680 &pathType, &count, &pause, path, color, clockPos1, clockPos2) >= 4) {

681 //ALOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s, clockPos1=%s, clockPos2=%s",

682 // pathType, count, pause, path, color, clockPos1, clockPos2);

683 Animation::Part part;

684 part.playUntilComplete = pathType == 'c';

685 part.count = count;

686 part.pause = pause;

687 part.path = path;

688 part.audioData = NULL;

689 part.animation = NULL;

690 if (!parseColor(color, part.backgroundColor)) {

691 ALOGE("> invalid color '#%s'", color);

692 part.backgroundColor[0] = 0.0f;

693 part.backgroundColor[1] = 0.0f;

694 part.backgroundColor[2] = 0.0f;

695 }

696 parsePosition(clockPos1, clockPos2, &part.clockPosX, &part.clockPosY);

697 animation.parts.add(part);

698 }

699 else if (strcmp(l, "$SYSTEM") == 0) {

700 // ALOGD("> SYSTEM");

701 Animation::Part part;

702 part.playUntilComplete = false;

703 part.count = 1;

704 part.pause = 0;

705 part.audioData = NULL;

706 part.animation = loadAnimation(String8(SYSTEM_BOOTANIMATION_FILE));

707 if (part.animation != NULL)

708 animation.parts.add(part);

709 }

710 s = ++endl;//每次循环删除字符串第一行

711 }

712

713 return true;

714 }

文件desc.txt的内容格式如下面的例子所示:

600 480 24

p   1   0   part1

p   0   10  part2

第一行的三个数字分别表示开机动画在屏幕中的显示宽度、高度以及帧速(fps)。剩余的每一行都用来描述一个动画片断,

这些行必须要以字符“p”来开头,后面紧跟着两个数字以及一个文件目录路径名称。第一个数字表示一个片断的循环显示次数,

如果它的值等于0,那么就表示无限循环地显示该动画片断。第二个数字表示每一个片断在两次循环显示之间的时间间隔。这个时间间隔是以一个帧的时间为单位的。文件目录下面保存的是一系列png文件,这些png文件会被依次显示在屏幕中。

以上面这个desct.txt文件的内容为例:

它描述了一个大小为600 x 480的开机动画,动画的显示速度为24帧每秒。这个开机动画包含有两个片断 part1 和 part2。片断part1只显示一次,它对应的png图片保存在目录part1中。片断part2无限循环地显示,其中,每两次循环显示的时间间隔为10 x (1 / 24)秒,它对应的png图片保存在目录part2中。

注意:开机动画资源制作成zip包的时候,压缩方式要注意一下,必须用存储的方式进行压缩,其他方式都不行,不然会导致无法正确读取desc.txt的资源而出现开机动画crash的情况,如下:

参考资料:https://blog.csdn.net/wangjun7121/article/details/88141376

你可能感兴趣的:(android,关机 流程)