android 开机动画实行流程

[复制链接]
发表于 2025-11-11 02:29:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
android深入相识开机动画

开机动画的种类

  1. 1:View绘制
  2. 2:逐帧动画:比较主流的方式,一般动画的文件打包成 bootanimation.zip 存储到 /system/media/ 下。一般.zip文件 > 5M 就会有明显的卡顿,所以一般开机动画只有中间一块有图案,四周是黑色,这样可以采用更小分辨率的图片。
  3. 3:OpenGL:定义了跨平台语言,跨平台的应用接口API规范,用于生成二维、三维图像。
复制代码
开机动画启动流程


      
  • 代码路径先容
         
    • bootanimation: /frameworks/base/cmds/bootanimation/   
    • surfaceflinger: /frameworks/native/services/surfaceflinger/   
    • init: /system/core/init/   
      
内核启动之后启动的第一个进程就是 init 进程,init进程会根据 init.rc 的设置启动 surfaceflinger 进程,在/frameworks/native/services/surfaceflinger/ 下有 surfaceflinger.rc 如下:
  1. 1 service surfaceflinger /system/bin/surfaceflinger
  2. 2     class core animation
  3. 3     user system
  4. 4     group graphics drmrpc readproc
  5. 5     onrestart restart zygote
  6. 6     writepid /dev/stune/foreground/tasks
复制代码
而 bootanim.rc 设置了 disabled ,因此在 init 进程分析时不会启动 bootanimation 进程。
  1. 1 service bootanim /system/bin/bootanimation
  2. 2     class core animation
  3. 3     user graphics
  4. 4     group graphics audio
  5. 5     disabled
  6. 6     oneshot
  7. 7     writepid /dev/stune/top-app/tasks
复制代码

      
  • surfaceflinger 进程启动以后,实行了 main_surfaceflinger.cpp 的 main 方法。
  1. 71  int main(int, char**) {
  2.    
  3.    
  4.                 // ..............
  5. 83      // start the thread pool
  6. 84      sp<ProcessState> ps(ProcessState::self());
  7. 85      ps->startThreadPool();
  8. 86  
  9. 87      // instantiate surfaceflinger 创建 SurfaceFlinger 实例
  10. 88      sp<SurfaceFlinger> flinger = new SurfaceFlinger();
  11. 89  
  12. 99      // 调用 flinger 的 init()
  13. 100      flinger->init();
  14. 101  
  15. 102      // publish surface flinger 将 flinger 服务添加到 ServiceManager 中。
  16. 103      sp<IServiceManager> sm(defaultServiceManager());
  17. 104      sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
  18. 105                     IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
  19. 106  
  20. 107      // publish GpuService
  21. 108      sp<GpuService> gpuservice = new GpuService();
  22. 109      sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
  23. 110
  24. 119      // run surface flinger in this thread 执行了 run() 方法
  25. 120      flinger->run();
  26. 121  
  27. 122      return 0;
  28. 123  }
复制代码
main_surfaceflinger.cpp 的 main 方法。,创建了 SurfaceFlinger 实例,并实行了其 init() 和 run() 方法。在 init() 函数中,有如下相干代码
  1. 637 void SurfaceFlinger::init() {
  2.    
  3.    
  4. 724    if (getHwComposer().hasCapability(
  5. 725            HWC2::Capability::PresentFenceIsNotReliable)) {
  6.    
  7.    
  8. 726        mStartPropertySetThread = new StartPropertySetThread(false);
  9. 727    } else {
  10.    
  11.    
  12. 728        mStartPropertySetThread = new StartPropertySetThread(true);
  13. 729    }
  14. 731    if (mStartPropertySetThread->Start() != NO_ERROR) {
  15.    
  16.    
  17. 732        ALOGE("Run StartPropertySetThread failed!");
  18. 733    }
  19. 739 }
复制代码
创建了一个 Thread 而且调用start() , 运行起来该线程以后看一看做了什么工作。接下来,看一下 StartPropertySetThread.cpp 的代码。
  1. 17#include <cutils/properties.h>
  2. 18#include "StartPropertySetThread.h"
  3. 19
  4. 20namespace android {
  5.    
  6.    
  7. 21
  8. 22StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):
  9. 23        Thread(false), mTimestampPropertyValue(timestampPropertyValue) {
  10.    
  11.    }
  12. 24
  13. 25status_t StartPropertySetThread::Start() {
  14.    
  15.    
  16. 26    return run("SurfaceFlinger::StartPropertySetThread", PRIORITY_NORMAL);
  17. 27}
  18. 28
  19. 29bool StartPropertySetThread::threadLoop() {
  20.    
  21.    
  22. 30    // Set property service.sf.present_timestamp, consumer need check its readiness
  23. 31    property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");
  24. 32    // Clear BootAnimation exit flag  这个不是结束,就是设置初始状态
  25. 33    property_set("service.bootanim.exit", "0");
  26. 34    // Start BootAnimation if not started 开启 BootAnimation 进程
  27. 35    property_set("ctl.start", "bootanim");
  28. 36    // Exit immediately
  29. 37    return false;
  30. 38}
  31. 39
  32. 40} // namespace android
  33. 41
复制代码
| property_set(“”, “”); 函数是Android框架中的一个函数,用于设置体系属性的值。体系属性是一种用于存储体系设置信息的键值对。property_set()函数的作用是将指定的属性名和属性值存储到体系属性中,而且举行后续动作和调解。
在之条件到的 /system/core/init/init.cpp 中,实行 main 函数有下面的代码
  1. 545 int main(int argc, char** argv) {
  2.    
  3.    
  4. 701    property_load_boot_defaults();
  5. 702    export_oem_lock_status();
  6. 703    start_property_service(); // 关键代码 启动监听 property 的服务
  7. 704    set_usb_controller();
  8. 790 }
复制代码
start_property_service(); 调用的是 /system/core/init/property_service.cpp 下的 start_property_service () 函数如下:
  1. 840 void start_property_service() {
  2.    
  3.    
  4. 841    selinux_callback cb;
  5. 842    cb.func_audit = SelinuxAuditCallback;
  6. 843    selinux_set_callback(SELINUX_CB_AUDIT, cb);
  7. 844
  8. 845    property_set("ro.property_service.version", "2");
  9. 846        // 创建了 Socket 来进行跨进程通信。
  10. 847    property_set_fd = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
  11. 848                                   false, 0666, 0, 0, nullptr);
  12. 849    if (property_set_fd == -1) {
  13.    
  14.    
  15. 850        PLOG(FATAL) << "start_property_service socket creation failed";
  16. 851    }
  17. 852        // 监听 property_set_fd  这个 fd
  18. 853    listen(property_set_fd, 8);
  19. 854        // 通过 epoll 机智,来监听 property_set_fd 是否有消息过来,如果有消息进来就会回调 handle_property_set_fd 方法。
  20. 855    register_epoll_handler(property_set_fd, handle_property_set_fd);
  21. 856 }
  22. 857
  23. 858 }
复制代码
上面报告了,监听到 property_set 以后,会调用到 handle_property_set_fd 方法,接下来看看,设置了 property_set(“ctl.start”, “bootanim”); 后实行流程是怎么样的。
  1. 481 static void handle_property_set_fd() {
  2.    
  3.    
  4. 482  
  5. 506
  6. 507    switch (cmd) {
  7.    
  8.    
  9. 508    case PROP_MSG_SETPROP: {
  10.    
  11.    
  12. 509        char prop_name[PROP_NAME_MAX];
  13. 510        char prop_value[PROP_VALUE_MAX];
  14. 521        const auto& cr = socket.cred();
  15. 522        std::string error;
  16.           // 主要代码
  17. 523        uint32_t result =
  18. 524            HandlePropertySet(prop_name, prop_value, socket.source_context(), cr, &error);
  19. 531        break;
  20. 532      }
  21. 533
  22. 534    case PROP_MSG_SETPROP2: {
  23.    
  24.    
  25. 535        std::string name;
  26. 536        std::string value;
  27. 546        uint32_t result = HandlePropertySet(name, value, socket.source_context(), cr, &error);
  28. 553        break;
  29. 554      }
  30. 555
  31. 556    default:
  32. 557        LOG(ERROR) << "sys_prop: invalid command " << cmd;
  33. 558        socket.SendUint32(PROP_ERROR_INVALID_CMD);
  34. 559        break;
  35. 560    }
  36. 561}
复制代码
上述代码,调用时,我们是设置属性,终极会调用到 HandlePropertySet() 函数,
[code][/code]
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表