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的环境,要求却是一样的。如下图:
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方法进入监听和接收消息的循环。
预加载过程:
- 预加载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对象。
- LoadApk对象的实例化
-
创建activityThread对象——ActivityThread.systemMain()方法研究
ActivityThread是一个Application的主线程类,(记住,它不是Thread,因为它既没有继承Thread,也没有实现Runnable)
由于SystemServer不是一个应用程序,但是这里为什么还要创建ActivityThread?因为SystemServer不仅仅是一个后台进程,同时它还是一个运行着组件的Service进程,很多系统的对话框就是从SystemServer中显示出来的,因此,SystemServer本身也需要一个和APK应用类似的上下文环境。- 创建ActivityThread实例
- 创建ApplicationThread对象。用于基于的BinderIPC通信
- 创建H对象mH,以及主线程的Looper对象mLooper
- ActivityThread的attach(boolean)方法的解析
- 创建Instrumentation对象
- 通过调用ContextImpl.createAppContext方法来创建ContextImpl对象
- 通过调用context.mPackageInfo.makeApplication创建mInitialApplication对象
- 调用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。
- LoadedApk的getClassLoader()方法的解析
- 创建ActivityThread实例
创建SystemServiceManager
把SystemServiceManager放到LocalServicesd的sLocalServiceObjects中,其中sLocalServiceObjects是一个ArrayMap。这样后面在通过类名,就可以找到SystemServiceManager的对象了。
启动各种服务
- startBootstrapServices();
- startCoreServices();
-
startOtherServices();
启动Launcher
SystemServer.java的startOtherServices()方法里面调用 mActivityManagerService.systemReady()方法,里面又会调用startHomeActivityLocked(mCurrentUserId, "systemReady");最后会调用startHomeActivity(Intent,ActivityInfo,String)方法。