Android开机启动过程

Android开机启动过程_第1张图片
Android开机图解.png
Android开机启动过程_第2张图片
Android开机图解2

Android系统启动过程

  • BootLoader与Linux内核启动
  • init进程
  • zygote进程
  • systemServer启动

init进程

init进程是Android系统启动的第一个进程。
init进程main方法做了如下工作:

  • first stage 初始化环境变量和各种文件系统目录,klog初始化等
  • selinux相关初始化完成,然后切换second stage 重启init进程
  • 属性服务初始化,将各种系统属性默认值填充到属性Map中
  • 创建epoll描述符结合注册socket监听,处理显示启动进程和挂掉的子进程重启
  • 解析init.rc。把各种action、service等解析出来的填充到相应链表容器管理
  • 有序将early-init、init等各种cmd加入到执行队列action_queue链表中
  • 进入while()循环依次取出执行队列action_queue中的command执行,fork包括app_process在内的各种进程,epoll阻塞监听处理来自挂掉的子进程的消息,根据设定策略restart子进程。

zygote进程

Zygote初始化时会创建创建虚拟机,同时把需要的系统类库和资源文件加载到内存里面。Zygote fork出子进程后,这个子进程也继承了能正常工作的虚拟机和各类系统资源,接下来子进程只需要装载APK文件的字节码文件就可以运行了。这样应用程序的启动时间就会大大缩短。
Zygote创建应用程序时却只使用了fork,没有调用exec。Android应用中执行的是Java代码,Java代码的不同才造成了应用的区别,而对于运行Java的环境,要求却是一样的。如下图:


Android开机启动过程_第3张图片
Zygote进程load Apk应用

Zygote进程创建AppRuntime对象。
AndroidRuntime类是安卓底层系统超级重要的一个类,它负责启动虚拟机以及Java线程。AndroidRuntime类是在一个进程中只有一个实例对象,并将其保存在全局变量gCurRuntime中。

AndroidRuntime类的start函数其实主要就是做了3件事情:
  • 创建了一个JniInvocation的实例,并且调用它的成员函数init来初始化JNI环境。
  • 调用AndroidRuntime类的成员函数startVm来创建一个虚拟机即其对应的JNI接口,即创建一个JavaVM接口和一个JNIEnv接口
  • 有了上述的JavaVM接口和JNIEnv接口之后,就可以在Zygote进程中加载指定的class了。

在AndroidRuntime中又创建了一个Runtime实例(Runtime在ART中代表Java的运行时环境。一个进程只有一个ATR虚拟机,一个ART虚拟机只有一个Runtime)。

在Runtime(Java运行时环境)准备完毕之后,Zygote会调用Java的初始化代码做如下工作:

  • 解析调用的参数,即argv[],通过for循环遍历解析,通过string的方法来判断,主要出是初始化startSystemServer、abiList和socketName变量
  • 调用registerZygoteSocket(socketName)方法注册Zygote的socket监听接口,用来启动应用程序的消息
  • 调用preload()方法装载系统资源,包括系统预加载类、Framework资源和openGL的资源。这样当程序被fork处理后,应用的进程内已经包含了这些系统资源,大大节省了应用的启动时间。
  • 调用startSystemServer()方法启动SystemServer进程。
  • 调动runSelectLooper方法进入监听和接收消息的循环。
Android开机启动过程_第4张图片
预加载系统类和资源

预加载过程:

  • 预加载Java类
  • 预加载资源
  • 预加载OpenGL资源
  • 预加载文本资源
  • 初始化WebView
zygote启动过程总结
  • 创建AppRuntime对象,并且调用其start函数。之后zygote的核心初始化都由AppRuntime中。
  • 调用startVm创建Java虚拟机,然后调用startReg来注册JNI函数
  • 通过JNI调用com.android.internal.os.ZygoteInit的main函数,从此进入了Java世界
  • 调用registerZygoteSocket创建可以响应子孙后台请求的socket。同时zygote调用preload函数预加载常用的类、资源等,为Java世界添砖加瓦
  • 调用startSystemServer函数fork一个system_server来为Java服务
  • Zygote完成了Java的初始工作后,便调用runSelectLoop来让自己无限循环等待。之后,如果收到子孙后台的请求,它便会醒来为他们工作。

SystemServer

SystemServer是Android系统的核心之一,大部分Android提供的服务都运行在这个进程里,SystemServer中运行的服务总共有60多种。为了防止应用进程对系统造成破坏,Android的应用进程没有权限直接访问设备的底层资源,只能通过SystemService中的代理访问。通过Binder,用户进程在使用SystemService中的服务并没有太多不便变之处。

SystemServer的主要工作如下:

  • 调用createSystemContext()来创建系统上下文
  • 创建SystemServiceManager
  • 启动各种服务
初始化系统上下文——createSystemContext()方法解析
  • 获取系统Context,即getSystemContext()

    • LoadApk对象的实例化
      LoadApk对象用来保存一个apk信息,这个构造方法中会将使用的包名指定为"android"。
      而framework-res.apk的包名为"android"。因此,getSystemServer()方法返回mSystemContext对象所对应的apk文件即是framework-res.apk
    • ContextImpl对象的实例化
      我们知道首次执行getSystemContext,会创建LoadedApk和contextImpl对象,接下来利用刚创建的LoadedApk对象来创建新的ContextImpl对象。
  • 创建activityThread对象——ActivityThread.systemMain()方法研究
    ActivityThread是一个Application的主线程类,(记住,它不是Thread,因为它既没有继承Thread,也没有实现Runnable)
    由于SystemServer不是一个应用程序,但是这里为什么还要创建ActivityThread?因为SystemServer不仅仅是一个后台进程,同时它还是一个运行着组件的Service进程,很多系统的对话框就是从SystemServer中显示出来的,因此,SystemServer本身也需要一个和APK应用类似的上下文环境。

    • 创建ActivityThread实例
      1. 创建ApplicationThread对象。用于基于的BinderIPC通信
      2. 创建H对象mH,以及主线程的Looper对象mLooper
    • ActivityThread的attach(boolean)方法的解析
      1. 创建Instrumentation对象
      2. 通过调用ContextImpl.createAppContext方法来创建ContextImpl对象
      3. 通过调用context.mPackageInfo.makeApplication创建mInitialApplication对象
      4. 调用mInitialApplication对象的onCreate()
        DropBox:DropBox是Android在Froyo(API 8)中引用的用来持续化存储系统数据的机制,主要记录Android运行过程中、内核、系统进程、用户进程等出现严重问题时的log,可以认为这是一个可持续存储的系统级别的log
        Instrumentation:一个应用进程,对应一个Instrumentation,这个类的对象,会被优先创建出来,然后通过它来创建其他组件,它也是系统与其他组件交互的桥梁,因此通过它可以监听组件和系统之间的各种交互。
        LoadedApk:在讲解APK安装的时候我们说过,一个应用对应一个LoadedApk对象,里面包含了整个APK的相关信息。其中context.mPackageInfo是一个LoadedApk对象
      
      • ContextImpl.createAppContext方法的解析
        直接new了一个ContextImpl对象
      • LoadedApk.makeApplication方法的解析
        • LoadedApk的getClassLoader()方法的解析
          区分是否是系统进程,系统进程通过ClassLoader.getSystemClassLoader()来获取系统的类加载器。
        • Instrumentation的newApplication(cl, appClass, appContext)方法的解析
          通过反射来创建一个Application的实例,最后调用attach(context)来绑定一个Context。
创建SystemServiceManager

把SystemServiceManager放到LocalServicesd的sLocalServiceObjects中,其中sLocalServiceObjects是一个ArrayMap。这样后面在通过类名,就可以找到SystemServiceManager的对象了。

启动各种服务
  • startBootstrapServices();
  • startCoreServices();
  • startOtherServices();


    Android开机启动过程_第5张图片
    system_server服务的启动流程
启动Launcher

SystemServer.java的startOtherServices()方法里面调用 mActivityManagerService.systemReady()方法,里面又会调用startHomeActivityLocked(mCurrentUserId, "systemReady");最后会调用startHomeActivity(Intent,ActivityInfo,String)方法。

Android开机启动过程_第6张图片
总结

参考文献

Android启动流程系列

你可能感兴趣的:(Android开机启动过程)