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的情况,如下:

Android 9.0 开关机动画流程分析_第1张图片

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

更多相关文章

  1. Android Studio生成APK文件名带上版本号等信息
  2. android文件管理器(1)
  3. 在android中获取文件的MD5值
  4. android获取assert资源文件
  5. Android Studio 导.so文件简单、高效的方法
  6. android 开源动画
  7. android 强制修改adb pull 文件的路径
  8. find ./ -name "hardware.*" 查找文件

随机推荐

  1. 看网易和腾讯如何用一套 H5 通杀Android(
  2. Android(安卓)开发者从0到1发布一个微信
  3. Android和iPhone应用程序界面布局示例
  4. Android(安卓)studio Gradle home can no
  5. 系统总结归纳一下android
  6. 作为一个IOS\android开发者,转行到RN的
  7. Android中图片实现按钮点击效果
  8. Android(安卓)7 强势来袭开发者们不得不
  9. Android的跨进程通信介绍---------------
  10. Android设计趋势分析10则