设为首页 收藏本站
查看: 1016|回复: 0

[经验分享] Android之system_server与zygote之作用

[复制链接]
YunVN网友  发表于 2018-10-17 07:10:22 |阅读模式
  第三天,
  google说,伊甸园(linux世界)要被隔离,于是便创造了亚当(Adm)与夏娃(Eve),称它为zygote和system_server
  --xxx
  第二天,init跑完了,它对于android系统,最重要的,就是启动了zygote和system-server,谁是Adam谁是Eve?
  从分析init.rc来看
?  --start-system-server只是个参数。
  分析源码
  啊,原来夏娃(zygote)用自己的肋骨(fork)创造了亚当(system_server)!什么?为什么不是亚当创造夏娃!?  android的世界,是无性繁殖的世界,zygote(夏娃)一开始就是个受精卵。。。。。。。
  Eve诞生记(zygote启动过程)
  第一步,受精(改名)
  从init.rc可以看出,启动的是app_process程序,启动后,再把自己的进程名改为zygote,就算是受精了。。
  第二步,着床(交由AppRuntime启动javaVM)
  这时,会创建一个vm,算是android java世界的祖师爷,并且在这个vm启动时赋予各种参数,比如我们都知道默认的情况下,一个应用程序加载的内存不能超过16mb,这个参数就是在这里设置的,heapsize为16mb。这之后vm就启动了,哦,应该叫dalvik。
  在启动后,还会为java的类注册JNI函数,android世界是c与java互相交织的。
  第三步,生长脐带(初涉java世界)
  注册好各种JNI函数后,zygote的C层面就可以调用Java代码了。
  这里第一次进入了java世界。它调用了  com.android.internal.os.ZygoteInit 的main方法。
  java世界并不孤立
  1、它首先注册socket,使自己成为一个服务端,也就是IPC通信服务端。这就是android的伟大之处,巧妙利用了linux的所有特性。以后会讲到zygote的真谛。
  2、然后预加载类以及一些android资源。洋洋洒洒1k多个java类要加载,并且还都是加载时间大于1250微妙的类,android框架加载耗时的类都到这里来加载了,这也正是android开机慢得原因,不过苦尽甘来吗,开始累点能干的都干了,以后用起来就方便了,不是么?当然,android的系统就像是量产车,各种性能不求最好只求最稳定,广大发烧友改rom就像改装汽车一样,需要精通从齿轮组到ECU的各种知识,方能达到硬件与软件完美的结合以便发挥出最大功效,扯多了。。要想定制rom,减少开机时间,还得靠nb的水平与良好的洞察力。
  3、启动SystemServer。也就是system_server进程。
  刚才说了,这个system_server就是Adm,夏娃的第一块肉就这么掉下来了,同样利用linux的fork机制,从zygote进程分裂出了一个system_server进程。男女搭配干活不累,亚当与夏娃共同劳动,为我们搭建美好的android世界。
  后面会分析system_server都干些什么事。
  4、建一个线程,转入socket侦听模式。每个apk在android中运行起来都是一个单独的linux进程,这些进程,就是zygote分裂出来的。现在zygote侦听的就是ActivityService通过system_server使用socket传入的请求,用以分裂进程。线程之外的最后,关闭之前打开的socket侦听。
  现在夏娃该干的事,基本上干完了,就等着亚当再次让她受精了。。。。。   -_-!!!!
  这里就顺便描述下每个Activity分娩出来的过程吧!(Activity大致启动过程)
  step 1 凡人向神求仔:
  启动一个activity,也就是startActivity。这个activity依附于一个未启动的进程,好比刚开机,打开一个android程序。
  step 2 大神收到祈愿:
  ActvityManagerService收到startActvity,梳理一番各种参数,比如apk的报名,再将这个祈愿通过送到伊甸园交由夏娃实施。
  step3 伊甸园接到生仔请求:
  亚当愿意别人直接找夏娃么?呵呵,各种service都是SystemServer启动起来的,而SystemServer又掌管着Binder,自己肯定会首先处理这个通知的。SystemServer通过socket这个IPC机制,向zygote发送一个fork请求,这时从java世界回到了native世界,亚当(system_server)让夏娃(zygote)受精了。。。。 -_-!!!  android的繁荣离不开这种造仔活动
  step4 夏娃生仔:
  又要分裂了,fork出了一个新进程,并把这个进程返还给Java世界,并且由ActivityManagerService管理它。这里,就是让这个进程调用ActivityThread,ActvityThread就是main,apk程序的main。
  linuix中fork出来的子进程会继承父进程的所有信息,就相当于一个拷贝,只不过变成了另一个进程。既然继承了所有信息,那么dalvik也就继承下来了,这就解释了为什么一个android程序都有一个vm进程。
  Adam诞生记(SystemServer启动过程)
  上面提到zygote在java层启动并fork了SystemServer,也就是夏娃身上掉下来的第一块肉。
  SystemServer首先会关闭因fork而从父进程继承而来的socket。
  第一步,Native层初始化
  这里会通过JNI调用native方法,又回到了Native世界。
  首先,初始化Skia引擎,就是一个图像引擎,封装了画图的各种操作,这样屏幕就能让显示东西了。
  然后,启动Binder,也就是android IPC的核心。
  第二步,换名,并进行JAVA层初始化
  换名了,这个vm进程就被正式命名为system_server了。
  java层初始化,也就是调用 com.android.server.SystemServer 的main。有趣的是,这里通过反射,获得SystemServer类的main方法后,不直接调用,而是抛出一个异常,这个异常包含了main这个Method。
  再回头看看zygote的java世界,启动了system_server的代码是在try中,catch中就是截获上面所说的异常,并执行main的这个Method。
  为什么这么做?
  先来看个示例程序:
?  上面这段代码模拟一个一个场景,方法A调用B,B又调用了C。。。  A()->B()->C()->final(),final里面可能又有更复杂的内容,而且final之后基本上不做什么了。真实情况下,A()与final()之间还有更多的调用层次。
  上面的调用栈情况是这样的:

  这样的话,在一些资源稀缺的平台上,,,,的确不怎么好,我们希望执行final的时候,前面调用的层次能消失,以前用过的变量什么也消失,还我们一个清净的世界,而且执行完了也不用再层层跳出了。
  这时,try catch就有大作用了,看代码:
?  与之前相比,把final()的调用换到了start()里,直接让c()抛出个异常,catch中执行final()。
  调用栈如下:

  Android的设计思想真猛啊,通过这么分析,又学到一个技巧。。。。
  SystemService->main
  1、加载native库并调用init1()
  这里创建了几个native服务, ServiceManger、SurfaceFlinger等,并把当前线程加入到Binder的通信大军中。
  2、通过JNI调用JAVA世界的init2()
  在上面的init1()中,最后会调用java世界的init2()。
  这里就是启动各种服务了,什么EntropyService、PowerManagerService、BatteryService、WindowManager等等。
  还会把地狱犬召唤出来,也就是WatchDog(看门狗),来时刻盯着一些重要的Service,防止他们堕落。看门狗的职责就是盯着一些重要的service,万一他们挂了,就把亚当杀死,然后让init把它再原地满血复活。
  最后,就进入了消息循环,负责android世界中跨线程访问的调度,google常曰 子线程要通过handler来更新UI线程,那么handler中发送的消息就是靠这里来分发的。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-622485-1-1.html 上篇帖子: Vmware VirtualCenter Server服务无法自动启动 下篇帖子: Redhat.Enterprise server4-----6.0
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表