Android 9.0 开关机动画流程分析
Android开机动画流程的启动主要是在Surfaseflinger里面完成的,具体代码如下:
/frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp32 bool StartPropertySetThread::threadLoop() {33 // Set property service.sf.present_timestamp, consumer need check its readiness34 property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");35 // Clear BootAnimation exit flag36 property_set("service.bootanim.exit", "0");37 // Start BootAnimation if not started38 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.rc1 service bootanim /system/bin/bootanimation2 class core animation3 user graphics4 group graphics audio5 disabled6 oneshot7 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 logo361 // 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 file658 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 unspecified670 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 Studio生成APK文件名带上版本号等信息
- android文件管理器(1)
- 在android中获取文件的MD5值
- android获取assert资源文件
- Android Studio 导.so文件简单、高效的方法
- android 开源动画
- android 强制修改adb pull 文件的路径
- find ./ -name "hardware.*" 查找文件