当前位置: 首页 > news >正文

烟台高端品牌网站建设如何学网站开发

烟台高端品牌网站建设,如何学网站开发,网站怎么做悬浮图片,网站后台图片做链接3. 第三个开机画面的显示过程第三个开机画面是由应用程序bootanimation来负责显示的。应用程序bootanimation在启动脚本init.rc中被配置成了一个服务#xff0c;如下所示#xff1a;service bootanim /system/bin/bootanimation user graphics group graphics disabled o…      3. 第三个开机画面的显示过程         第三个开机画面是由应用程序bootanimation来负责显示的。应用程序bootanimation在启动脚本init.rc中被配置成了一个服务如下所示 service bootanim /system/bin/bootanimation       user graphics       group graphics       disabled       oneshot          应用程序bootanimation的用户和用户组名称分别被设置为graphics。注意 用来启动应用程序bootanimation的服务是disable的即init进程在启动的时候不会主动将应用程序bootanimation启动起来。当SurfaceFlinger服务启动的时候它会通过修改系统属性ctl.start的值来通知init进程启动应用程序bootanimation以便可以显示第三个开机画面而当System进程将系统中的关键服务都启动起来之后ActivityManagerService服务就会通知SurfaceFlinger服务来修改系统属性ctl.stop的值以便可以通知init进程停止执行应用程序bootanimation即停止显示第三个开机画面。接下来我们就分别分析第三个开机画面的显示过程和停止过程。       从前面Android系统进程Zygote启动过程的源代码分析一文可以知道Zygote进程在启动的过程中会将System进程启动起来而从前面Android应用程序安装过程源代码分析一文又可以知道System进程在启动的过程Step 3中会调用SurfaceFlinger类的静态成员函数instantiate来启动SurfaceFlinger服务。Sytem进程在启动SurfaceFlinger服务的过程中首先会创建一个SurfaceFlinger实例然后再将这个实例注册到Service Manager中去。在注册的过程前面创建的SurfaceFlinger实例会被一个sp指针引用。从前面Android系统的智能指针轻量级指针、强指针和弱指针的实现原理分析一文可以知道当一个对象第一次被智能指针引用的时候这个对象的成员函数onFirstRef就会被调用。由于SurfaceFlinger重写了父类RefBase的成员函数onFirstRef因此在注册SurfaceFlinger服务的过程中将会调用SurfaceFlinger类的成员函数onFirstRef。在调用的过程就会创建一个线程来启动第三个开机画面。        SurfaceFlinger类实现在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp 中它的成员函数onFirstRef的实现如下所示 void SurfaceFlinger::onFirstRef()   {       run(SurfaceFlinger, PRIORITY_URGENT_DISPLAY);          // Wait for the main thread to be done with its initialization       mReadyToRunBarrier.wait();   }           SurfaceFlinger类继承了Thread类当它的成员函数run被调用的时候系统就会创建一个新的线程。这个线程在第一次运行之前会调用SurfaceFlinger类的成员函数readyToRun来通知SurfaceFlinger它准备就绪了。当这个线程准备就绪之后它就会循环执行SurfaceFlinger类的成员函数threadLoop直到这个成员函数的返回值等于false为止。         注意SurfaceFlinger类的成员函数onFirstRef是在System进程的主线程中调用的它需要等待前面创建的线程准备就绪之后再继续往前执行这个通过调用SurfaceFlinger类的成员变量mReadytoRunBarrier所描述的一个Barrier对象的成员函数wait来实现的。每一个Barrier对象内问都封装了一个条件变量Condition Variable而条件变量是用来同步线程的。         接下来我们继续分析SurfaceFlinger类的成员函数readyToRun的实现如下所示 status_t SurfaceFlinger::readyToRun()   {       LOGI(   SurfaceFlingers main thread ready to run.                Initializing graphics H/W...);              ......          mReadyToRunBarrier.open();          /*       *  Were now ready to accept clients...       */          // start boot animation       property_set(ctl.start, bootanim);          return NO_ERROR;   }          前面创建的线程用作SurfaceFlinger的主线程。这个线程在启动的时候会对设备主屏幕以及OpenGL库进行初始化。初始化完成之后接着就会调用SurfaceFlinger类的成员变量mReadyToRunBarrier所描述的一个Barrier对象的成员函数open来唤醒System进程的主线程以便它可以继续往前执行。最后SurfaceFlinger类的成员函数readyToRun的成员函数会调用函数property_set来将系统属性“ctl.start”的值设置为“bootanim”表示要将应用程序bootanimation启动起来以便可以显示第三个开机画面。        前面在介绍第二个开机画面的时候提到当系统属性发生改变时init进程就会接收到一个系统属性变化通知这个通知最终是由在init进程中的函数handle_property_set_fd来处理的。        函数handle_property_set_fd实现在文件system/core/init/property_service.c中如下所示 void handle_property_set_fd()   {       prop_msg msg;       int s;       int r;       int res;       struct ucred cr;       struct sockaddr_un addr;       socklen_t addr_size  sizeof(addr);       socklen_t cr_size  sizeof(cr);          if ((s  accept(property_set_fd, (struct sockaddr *) addr, addr_size))  0) {           return;       }          /* Check socket options here */       if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, cr, cr_size)  0) {           close(s);           ERROR(Unable to recieve socket options\n);           return;       }          r  recv(s, msg, sizeof(msg), 0);       close(s);       if(r ! sizeof(prop_msg)) {           ERROR(sys_prop: mis-match msg size recieved: %d expected: %d\n,                 r, sizeof(prop_msg));           return;       }          switch(msg.cmd) {       case PROP_MSG_SETPROP:           msg.name[PROP_NAME_MAX-1]  0;           msg.value[PROP_VALUE_MAX-1]  0;              if(memcmp(msg.name,ctl.,4)  0) {               if (check_control_perms(msg.value, cr.uid, cr.gid)) {                   handle_control_message((char*) msg.name  4, (char*) msg.value);               } else {                   ERROR(sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n,                           msg.name  4, msg.value, cr.uid, cr.pid);               }           } else {               if (check_perms(msg.name, cr.uid, cr.gid)) {                   property_set((char*) msg.name, (char*) msg.value);               } else {                   ERROR(sys_prop: permission denied uid:%d  name:%s\n,                         cr.uid, msg.name);               }           }           break;          default:           break;       }   }           init进程是通过一个socket来接收系统属性变化事件的。每一个系统属性变化事件的内容都是通过一个prop_msg对象来描述的。在prop_msg对象对成员变量name用来描述发生变化的系统属性的名称而成员变量value用来描述发生变化的系统属性的值。系统属性分为两种类型一种是普通类型的系统属性另一种是控制类型的系统属性属性名称以“ctl.”开头。控制类型的系统属性在发生变化时会触发init进程执行一个命令而普通类型的系统属性就不具有这个特性。注意改变系统属性是需要权限因此函数handle_property_set_fd在处理一个系统属性变化事件之前首先会检查修改系统属性的进程是否具有相应的权限这是通过调用函数check_control_perms或者check_perms来实现的。         从前面的调用过程可以知道当前发生变化的系统属性的名称为“ctl.start”它的值被设置为“bootanim”。由于这是一个控制类型的系统属性因此在通过了权限检查之后另外一个函数handle_control_message就会被调用以便可以执行一个名称为“bootanim”的命令。 本文转自 Luoshengyang 51CTO博客原文链接http://blog.51cto.com/shyluo/967040如需转载请自行联系原作者
http://www.zqtcl.cn/news/129462/

相关文章:

  • 网站建设预付流程网站设计风格的关键词
  • 常德网站制作怎么做自己的网页
  • 做的网站为什么图片看不了wordpress循环该分类子分类
  • 源码出售网站怎么做一个产品的网络营销方案
  • 安丘营销型网站建设国外教育网站模板
  • 做网站案例百度小说排行榜前十
  • 东昌网站建设公司上传到网站去的文档乱码
  • 如何制作自己的网站链接教程网络营销seo招聘
  • 网站制作资料收集wordpress资源网模板
  • 随州网站设计开发服务做网站制作步骤
  • 东莞凤岗做网站黄山旅游攻略住宿
  • 网站开发常用插件免费库存管理软件哪个好
  • 河池网站开发工程师招聘网如何做品牌运营与推广
  • 做网站运营难吗零基础网站建设教程
  • 深圳蚂蚁网络网站建设wordpress电影主题
  • 网站域名收费吗搜索引擎不收录网站
  • 海兴网站建设价格wordpress替代软件
  • 做网站哪家服务器好小区物业管理系统
  • 上海推广网站公司网站建设首选
  • 网站建设行业分析报告网站建设视频教程
  • 服装网站建设图企业网站建设开题报告是什么
  • 建设外贸商城网站制作网站建设的中期目标
  • 网站定做地方门户网站带手机版
  • 佛山网站建设哪家评价高系统开发报价清单
  • 东莞道滘网站建设做h游戏视频网站
  • 江西营销网站建设公司网站建设 意义
  • 公司网站怎么自己做织梦品牌集团公司网站模板(精)
  • 西安市高陵区建设局网站产品网站做营销推广
  • 网站开发费是无形资产吗深圳网站建设简介
  • 网站开发架构mvc重庆巫山网站设计哪家专业