Android启动流程相关

Android的启动流程

1、按下电源键之后,会引导芯片代码从预定义的地方(固化在rom了)开始执行,加载引导程序BootLoader加载到RAM,然后执行。Bootloader是一段小型的程序,主要功能是将内核映像从闪存加载到内存。

2、会生成第一个进程idle(pid=0),会初始化进程管理、内存管理和一些驱动。

3、idle会生成两个进程。pid=1 的init进程,是用户空间的鼻祖,pid=2的kthreadd的内核空间鼻祖,它会创建内核工作线程、软中断等内核守护进程。

4、init进程会创建和挂在文件系统,初始化和启动系统服务,并给子进程创建信号处理函数防止僵尸进程出现。通过(init.rc配置文件)fork java进程的鼻祖,zygote。

5、zygote,会启Java虚拟机,注册jni方法和预加载类和资源。并使用jni方法调用zygoteInit的main方法。

6、ZygoteInit中创建一个 Server端的socket用于客户端发出创建应用的请求。预加载类和资源和启动SystemServer进程,并等待AMS的创建进程请求。

会fork systemServer进程,通过socket进行通信。

5、systemServer通过AMS通过socket与zygote通信,然后创建app进程

image.png

init进程的启动

step1 FirstStageMain

   初始化crash重启引导加载程
   挂载 创建文件
   重定向输入输出
   初始化内核的日志打印
   启动seLinux_setup

step2 SetupSelinux

   提高Linux安全,约束访问权限。

step3 SecondStageMain

    监听进程终止信号,清除僵尸进程
    解析inir.rc(执行zygote 执行重启)
    向队列中添加action
    循环处理脚本中的事件

总结起来就是init

    1、挂在和创建系统文件
    2、解析rc文件
    3、进入无线循环
            1、执行action -- zygote启动
            2、检测并重启进程
            3、接收子进程的SIGCHILD信号,执行响应的方法,防止成为僵尸进程

zygote: 1、native 1、初始化Android运行环境 2、注册jni 3、执行zygoteInit.main方法进入java层

2、Java 1、创建socket 2、执行预加载 3、通过fork创建systemServer进程 4、进入循环:等待AMS的通知,创建对应的进程

zygote执行流程

1、手机开机后会执行init文件,启动init.rc脚本,在脚本里启动zygote

2、来到app_main.CPP

    初始化AndroidRuntime
    设置zygote为启动模式,strcmp(arg,"--zygote")
    给start函数的参数args赋值
    runtime.start()启动Zygoteinit
            
    zygoteinit创建虚拟机、注册JNI然后Zygote的main函数
    
    ZygoteInit .MAIN  
            预加载   
            创建socket   
            创建systemServer  
            systemserver 的 main方法    
            无限循环
            

孵化应用进程为什么不交给SystemServer来做,而是专门设计一个Zygote?

zygote是所有android应用进程的母体,zygote在启动时做了很多耗时操作,比如启动虚拟机,注册jni方法,预加载系统资源。子进程使用fork孵化进程的方式继承了这些资源,并可以直接使用而不需要重新加载,提高了应用启动的速度和性能。

而SystemServer中注册了很多系统服务,而在应用子进程中都是不需要的。

App的启动流程

1、Laucnher也就是桌面图标被点击,转到Instrumentation类的startActivity方法

2、Instrument通过跨进程通信报告AMS要启动应用的需求

3、AMS反馈Launcher,让它进入到Pause状态

4、Launcher进入Paused状态,AMS转到ZygoteProcess类,并通过socket与Zygote通信,告诉Zygote需要新建进程。

5、Zygote fork进程,并调用ActivityThread的main方法,也就是App的入口

6、ActivityThread的main方法新建了ActivityThread的实例,并新建了Looper实例,开始loop循环

7、ActivityThread告诉AMS,进程创建完毕,开始穿件Application,provide,并调用Application的attach和onCreate方法

5、最后就是创建上下文,通过类加载器加载Activity,调用Activity的onCreate方法

image.png

讲一下fork机制

fork机制有个核心点就是Copy_on_Write机制。

fork作用是复制一个当期进程副本,且父子共享物理内存地址,但内存页权限为read_only,父子只读。如果一方写入,则会触发页异常中断。陷入kernel的中断例程,kernel就会把触发的异常页复制一份,父子各持一份,这就是copy_on_write机制。 有点减少分配和复制资源的延时减少资源分配,因为fork的子线程并不是所有 页面都要父进程的。

讲以下systemServer、ServiceManager、SystemServerManager的区别

1.SystemServer是孵化进程启动后,开启的第一个系统服务进程,该进程主要作用是启动和注册android系统依赖的各种服务并启动桌面Launcher

2.ServiceManager调用addService()可以将服务注册到系统服务管理进程SM中,getService()方法在SM中获取服务。ServieManager里的add get操作都是由ServiceManagerProxy来操作,内部包含一个BpBinder,它的handler为0,表示服务端为SM进程。

驱动端收到handler为0就可以拿到SM的binder_proc

ServiceManager的addService其实是调用的ServiceManagerProxy代理类的addService和getService操作,ServiceManagerProxy内部包含一个BpBinder,这个BpBinder的handle为0,表示服务端为SM进程

驱动程序在收到handle=0时,可以得到SM的binder_proc,可以通过操作这个binder_proc,将数据放到他的todo链表中并唤醒线程,从而在SM进程中通过name获取服务端的IBinder

【这个是详细版本,有兴趣可以了解下。】

驱动收到这个handle,则会从SM的binder_proc中找到服务端的binder_ref,通过binder\_ref找到binder_node,并给客户端的binder_proc创建一个binder_ref,这个binder_ref的binder_node指向服务端的binder_node

并把生产的binder_ref的desc序号返回给客户端,客户端通过这个desc,将desc包裹在BpBinder里面,将BpBinder包裹在BinderProxy对象中,

使用服务的过程会调用RPC层的BinderProxy.transact发送数据,最终到内核里面会使用到被BpBinder包裹的desc,通过这个desc从客户端的binder_ref中找到binder_node,通过binder_node找到binder_proc

并将数据放到服务端的binder_proc下面的binder_thread线程的todo链表中,并唤醒线程,线程被唤醒后,首先会获取数据的cookie值,里面存储的是服务注册的时候放入的服务对象的地址,最终会调用到BBinder的transact,最终调用到服务端的IBinder对象的方法

3、SystemServiceManager是在SystemServer启动之后生成的一个系统服务管理者,可以启动系统服务并控制生命周期。

SystemServiceManager:用来管理服务生命周期的 ServerManger:管理Binder服务的

ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService); ServiceManager.addService(name, service, allowIsolated, dumpPriority); // 注册Binder服务

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务