android体系课-系统启动流程-之SystemServer启动过程源码分析

简介: 笔者刚开始学习Android的时候也和大部分同学一样,只会使用一些应用层面的知识,对于一些比较常见的开源框架如<mark>RxJava</mark>,<mark>OkHttp</mark>,<mark>Retrofit</mark>,以及后来谷歌推出的<mark>协程</mark>等,都只在使用层面,对于他们<mark>内部原理</mark>,基本没有去了解觉得够用就可以了,又比如Activity,Service等四大组件的使用原理,系统开机过程,Launcher启动过程等知之甚少,知其然而不知其所以然,结果就是出现某些问题,不知道从哪里找原因,只能依赖万能的百度,但是百度看多了,你会发现自己

前言

本文主要记录笔者对Android系统启动流程的一个的一个过程了解

笔者刚开始学习Android的时候也和大部分同学一样,只会使用一些应用层面的知识,对于一些比较常见的开源框架如RxJava,OkHttp,Retrofit,以及后来谷歌推出的协程等,都只在使用层面,对于他们内部原理,基本没有去了解觉得够用就可以了,又比如Activity,Service等四大组件的使用原理,系统开机过程,Launcher启动过程等知之甚少,知其然而不知其所以然,结果就是出现某些问题,不知道从哪里找原因,只能依赖万能的百度,但是百度看多了,你会发现自己还是什么都不会,过一段时间可能就忘记了

  • 为了能更加深刻的理解这些机制,笔者决定自己深入Framework层面去考察下这些代码的机制:

讲解时间线如下:

对于源码解析部分,可能大家会有部分疑惑,我们列出部分:

  • 1.zygoye是什么?有什么作用

    答:zygote英文翻译是“孵化”。

在了解zygote之前首先我们需要知道我们进程是如何创建的?

我们安卓设备内核使用的是linux内核,
开机先是启动一个init进程,在init进程中会创建一个zygote进程,
zygote进程会启动java虚拟机并注册java-native 的jni方法,通过jni调用到java层的ZygoteInit,在这个类里面会注册一个ServerSocket用于设备创建应用进程的需要。
当启动一个应用需要创建一个进程时,会调用到这个ServerSocket的创建进程流程,主要是通过fork的方式创建进程,这样子进程就拥有了父进程所有的资源,
fork会返回两次,当返回的pid=0时说明现在是处于子进程,继续处理子进程流程就可以了。如果是SystemServer进程,则会启动各类服务,包括AMS,WMS等系统服务。

按上面所讲,zygote就是作为创建子进程的一个孵化器。

  • 2.SystemServer是什么?有什么作用?它与zygote的关系是什么?

答:SystemServer是一个由zygotefork出来的子进程,该进程主要作用是创建创建binder线程池和启动android运行需要的诸多系统服务,比如:AMS,PMS,WMS等并启动系统Launcher

  • 3.ActivityManagerService是什么?什么时候初始化的?有什么作用?

答:ActivityManagerService,简称AMS,服务端对象,负责统一调度系统中四大组件的生命周期。ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService

**APP和AMS其实是通过binder进行通讯的。**

binder机制简述。
    binder其实是进程间通信的一种方式,在linux进程中有socket,管道,共享内存,消息队列等方式,
    而由于binder对性能消耗低和安全性方面的考虑,android大量的使用了binder通讯 ,可以说binder是android的基石。
binder模型简述:
    首先我们binder是通过CS架构进行设计的:Client和Service
    先搞懂三个概念:client,server和serverManger
    server通过binder通讯将自己注册到serverManager中,client通过binder获取serverManager中注册的server,
    其实是获取一个handle,通过这个handle就可以在bidner驱动中找找到server进程和需要处理的方法地址等信息。
    从而间接实现了进程间通讯,这个是binder的一个简要概述,详细的需要去了解binder驱动实现原理。
  • 4.Launcher是什么?什么时候启动的?

    答:Launcher也是一个应用app,是在SystemServer启动的时候,启动的一个应用
    
  • 5.Instrumentation是什么?和ActivityThread是什么关系?

    答:Instrumentation是一个沟通Activity和AMS以及ActivityThread和Activity中间桥梁工具类
    例如:Activity.startActivity

        ->mInstrumentation.execStartActivity
        ->ActivityManagerService.startActivity->ActivityThread.thread.scheduleLaunchActivity
        ->ActivityThread.handleLaunchActivity
        ->mInstrumentation.callActivityOnCreate
    

针对以上问题:笔者会以源码的方式呈现

前面一篇文章我们已经介绍过了Android系统启动-zygote进程详解:

android体系课-系统启动流程-之zygote进程启动过程源码分析

下面我们来分析下SystemServer的启动过程。

介绍SystemServer前我们先来分析下系统启动的几个关键字:

  • init.cpp
    linux系统启动第一个进程:

    1.mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");挂载临时文件系统

    2.selinux_initialize(true);启动selinux 主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)

    3.InitKernelLogging(argv);初始化内核日志

    4.property_init();对属性服务进行初始化

    5.signal_handler_init();设置信号处理函数,如果子进程(Zygote)进程异常退出,会调用该函数设置的信号函数进行处理

    6.start_property_service();启动属性服务

    7.解析init.rc文件
  • init.rc
    由android初始化语言编写的脚本文件
    主要作用是启动Zygote进程:
    启动方式:fork子进程,会启动app_main.cpp的main函数
  • app_main.cpp
    根据参数判断启动哪个进程:
case strcmp(arg, "--zygote") == 0:
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);

case strcmp(arg, "--start-system-server") == 0:
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
开机启动阶段参数中含有--zygote
启动的是ZygoteInit进程,进入AndroidRuntime。
  • AndroidRuntime.cpp

    • 1.startVm(&mJavaVM, &env, zygote)启动java虚拟机
    • 2.startReg(env)注册jni方法:
      register_jni_procs(gRegJNI, NELEM(gRegJNI), env)
    • 3.env->CallStaticVoidMethod(startClass, startMeth, strArray);调用java方法:ZygoteInit的main方法,进入java代码
    startClass = com.android.internal.os.ZygoteInit
  • ZygoteInit.java

    • 1.zygoteServer.registerServerSocket(socketName);

      注册一个ServerSocket,文件名:ANDROID_SOCKET_zygote
      
      mServerSocket = new LocalServerSocket(fd);
                              impl = new LocalSocketImpl(fd);
                              impl.listen(LISTEN_BACKLOG);
                                      Os.listen(fd, backlog);
    • 2.startSystemServer

      启动SystemServer进程,这里是SystemServer核心处理代码。
      
//fork出SystemServer进程 fork操作会返回两次,一次是父进程一次是子进程
        pid = Zygote.forkSystemServer() 
        //pid=0说明运行在子线程SystemServer进程
        if(pid ==0){    
            zygoteServer.closeServerSocket();
            //处理SystemServer进程
            handleSystemServerProcess(parsedArgs);
                ZygoteInit.zygoteInit();
                    //RuntimeInit初始化
                    RuntimeInit.commonInit();
                    //创建binder线程池
                    ZygoteInit.nativeZygoteInit();
                    RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
                        invokeStaticMain(args.startClass, args.startArgs, classLoader);
                            throw new Zygote.MethodAndArgsCaller(m, argv);
                            //会跳转到ZygoteInit的main方法中,class: SystemServer method: main
                            catch (Zygote.MethodAndArgsCaller caller) { 
                                caller.run();
                                    main(){
                                        // Ensure binder calls into the system always run at foreground priority.
                                        //这个就是为什么在服务保活的时候,在需要保活的服务里面启动另外一个服务可以让该保活的服务在前台,提高其优先级
                                        BinderInternal.disableBackgroundScheduling(true);
                                        //设置系统最大的binder驱动线程 sMaxBinderThreads = 31个
                                        BinderInternal.setMaxThreads(sMaxBinderThreads);
                                        //创建SystemServer应用的looper
                                        Looper.prepareMainLooper();
                                        //加载SystemServer需要的so库
                                        System.loadLibrary("android_servers");
                                        //创建SystemServer应用的context
                                        Looper.prepareMainLooper();
                                        // Initialize the system context.
                                        createSystemContext();
                                            //创建ActivityThread,应用进程方法入口
                                            ActivityThread activityThread = ActivityThread.systemMain();
                                                ActivityThread thread = new ActivityThread();
                                                thread.attach(true);
                                                if(!isSystem){            
                                                    //从ServiceManager中获取 ActivityManagerService
                                                    final IActivityManager mgr = ActivityManager.getService();  
                                                    //将ActivityThread中的ApplicationThread发给AMS,此后AMS就可以使用该mAppThread调用ActivityThread中的方法。        
                                                    mgr.attachApplication(mAppThread); 
                                                }else{
                                                    ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
                                                    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                                                    mInitialApplication.onCreate();
                                                }
                                            //创建进程的上下文context
                                            mSystemContext = activityThread.getSystemContext();
                                                ContextImpl.createSystemContext(this);
                                                    //创建LoadedApk
                                                    LoadedApk packageInfo = new LoadedApk(mainThread);
                                                    //创建context
                                                    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null);
                                                    //设置context的resources
                                                    context.setResources(packageInfo.getResources());
                                            //设置系统Theme:com.android.internal.R.style.Theme_DeviceDefault_System
                                            mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
                                        //注册过程有addService和startService,前者是将服务注册到ServiceManager中后者是将服务注册到本地SystemServerManager中。
                                        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
                                        //启动引导服务
                                        startBootstrapServices();
                                        //启动核心服务
                                        startCoreServices();
                                        //启动其他服务
                                        startOtherServices();
                                            //启动Launcher
                                            mActivityManagerService.systemReady(() -> {}
                                            AMS:systemReady:
                                                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
                                            ActivityStackSupervisor.java:resumeFocusedStackTopActivityLocked:
                                                            resumeFocusedStackTopActivityLocked(null, null, null);
                                                                //开始的时候r=ActivityRecord为null
                                                                if (r == null || r.state != RESUMED) {
                                                                    mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
                                            ActivityStack.java:resumeTopActivityUncheckedLocked:
                                                                        result = resumeTopActivityInnerLocked(prev, options);
                                                                            return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(prev, "prevFinished");
                                            ActivityStackSupervisor.java:resumeHomeStackTask
                                                                                return mService.startHomeActivityLocked(mCurrentUser, myReason);
                                            AMS:startHomeActivityLocked
                                                                                    Intent intent = getHomeIntent();//获取Launcher Intent
                                                                                    mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
                                            ActivityStarter.java:startHomeActivityLocked:
                                                                                        mSupervisor.moveHomeStackTaskToTop(reason);Returns true if the focus activity was adjusted to the home stack top activity
                                                                                        startActivityLocked
                                                                                            startActivity//这里启动了Launcher的MainActivity
                                        //可看出SystemServer进程也使用了Looper消息处理机制
                                        Looper.loop();
                                    }                                    
                            } 
        }
    //Zygote进程会继续执行下面的语句。    
    3.zygoteServer.runSelectLoop(abiList);
             while (true) {
                StructPollfd[] pollFds = new StructPollfd[fds.size()];
                for (int i = 0; i < pollFds.length; ++i) {
                    pollFds[i] = new StructPollfd();
                    pollFds[i].fd = fds.get(i);
                    pollFds[i].events = (short) POLLIN;
                }
                try {
                    //poll函数使用pollfd类型的结构来监控一组文件句柄
                    //https://blog.csdn.net/sijinxiaotongxue/article/details/81988411
                    Os.poll(pollFds, -1);
                } catch (ErrnoException ex) {
                    throw new RuntimeException("poll failed", ex);
                }
                for (int i = pollFds.length - 1; i >= 0; --i) {
                    //返回的事件掩码被设置为POLLIN说明可读,如果不是POLLIN则继续看下一个Fd是否为POLLIN;
                    if ((pollFds[i].revents & POLLIN) == 0) {
                        continue;
                    }
                    //此处的pollFds->revents为POLLIN说明可读,i=0说明有客户端做连接操作,服务端则调用accept操作,这样就创建了连接。把连接上的fd放入需要监听的fds中,继续while监听。
                    if (i == 0) {
                        //新建一个ZygoteConnection
                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                            //获取sokcet客户端传过来的数据并封装到ZygoteConnection中。
                            LocalSocket localSocket = mServerSocket.accept();
                            createNewConnection(localSocket, abiList);
                                new ZygoteConnection(socket, abiList);
                        peers.add(newPeer);
                        fds.add(newPeer.getFileDesciptor());
                        
                    } else { i!=0
                        //不为0则说明签名i=0放入的fd句柄有事件,调用fork方式创建进程
                        boolean done = peers.get(i).runOnce(this);
                            //读参数
                            args = readArgumentList();
                            //fork出子进程
                            pid = Zygote.forkAndSpecialize(args);
                            if (pid == 0) {
                                // pid=0说明在子进程中
                                zygoteServer.closeServerSocket();            
                                //处理子进程    
                                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);        
                                    ZygoteInit.zygoteInit();
                                        //RuntimeInit初始化
                                        RuntimeInit.commonInit();
                                        //创建binder线程池
                                        ZygoteInit.nativeZygoteInit();
                                        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
                                            invokeStaticMain(args.startClass, args.startArgs, classLoader);
                                                throw new Zygote.MethodAndArgsCaller(m, argv);
                                                会跳转到ZygoteInit的main方法中,如果是子进程则为ActivityThread类的main方法,或者是SystemServer进程的main方法
                                                catch (Zygote.MethodAndArgsCaller caller) {
                                                    caller.run();
                                                } 
                                return true;
                            } else {
                                // in parent...pid of < 0 means failure    
                                //处理父进程
                                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
                            }
                        if (done) {
                            //移除连接
                            peers.remove(i);
                            fds.remove(i);
                        }
                    }
                }
            }
        PS:这里的为什么是i=0为连接操作呢,因为pollFds的第一个元素的fd字段为socket监听的fd文件。
        而i>0的情况为i=0获取到连接信息时fds.add(newPeer.getFileDesciptor());添加的fd,索引肯定大于0,
        这里巧妙的用了索引位置的关系,节省了一些代码

    3.zygoteServer.closeServerSocket(); 一般只有zygote进程退出的时候才会走到这里,也就是关机的时候才会,前面while循环会一直等待AMS发起创建fork进程的操作    

总结下SystemServer进程:

  • 1.SystemServer创建方式:fork
  • 2.SystemServer进程做了哪些事情:

    • 2.1:创建binder线程池
    • 2.2:调用BinderInternal.disableBackgroundScheduling(true):可以确保需要保活的服务里面启动另外一个服务可以让该保活的服务在前台,提高其优先级
    • 2.3:设置系统最大的binder驱动线程
    • 2.4:加载运行SystemServer需要的so库
    • 2.5:创建SystemServer应用的上下文context
    • 2.6:启动引导服务,启动核心服务,启动其他服务等系统服务
    • 2.7:在启动其他服务中,启动launcher
    • 2.8:SystemServer也是要了Looper机制,只是这个是系统的应用

关于SystemServer的运行就讲到这里。
下一篇我们会讲解关于startActivity源码方面的机制:根Activity启动和普通Activity启动方式

相关文章
|
21天前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
45 15
Android 系统缓存扫描与清理方法分析
|
12天前
|
算法 JavaScript Android开发
|
14天前
|
安全 搜索推荐 Android开发
揭秘安卓与iOS系统的差异:技术深度对比
【10月更文挑战第27天】 本文深入探讨了安卓(Android)与iOS两大移动操作系统的技术特点和用户体验差异。通过对比两者的系统架构、应用生态、用户界面、安全性等方面,揭示了为何这两种系统能够在市场中各占一席之地,并为用户提供不同的选择。文章旨在为读者提供一个全面的视角,理解两种系统的优势与局限,从而更好地根据自己的需求做出选择。
36 2
|
22天前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
|
13天前
|
安全 搜索推荐 程序员
深入探索Android系统的碎片化问题及其解决方案
在移动操作系统的世界中,Android以其开放性和灵活性赢得了广泛的市场份额。然而,这种开放性也带来了一个众所周知的问题——系统碎片化。本文旨在探讨Android系统碎片化的现状、成因以及可能的解决方案,为开发者和用户提供一种全新的视角来理解这一现象。通过分析不同版本的Android系统分布、硬件多样性以及更新机制的影响,我们提出了一系列针对性的策略,旨在减少碎片化带来的影响,提升用户体验。
|
13天前
|
安全 Android开发 iOS开发
深入探索iOS与Android系统的差异性及优化策略
在当今数字化时代,移动操作系统的竞争尤为激烈,其中iOS和Android作为市场上的两大巨头,各自拥有庞大的用户基础和独特的技术特点。本文旨在通过对比分析iOS与Android的核心差异,探讨各自的优势与局限,并提出针对性的优化策略,以期为用户提供更优质的使用体验和为开发者提供有价值的参考。
|
15天前
|
安全 Android开发 iOS开发
安卓系统与iOS系统的比较####
【10月更文挑战第26天】 本文将深入探讨安卓(Android)和iOS这两大主流移动操作系统的各自特点、优势与不足。通过对比分析,帮助读者更好地理解两者在用户体验、应用生态、系统安全等方面的差异,从而为消费者在选择智能手机时提供参考依据。无论你是技术爱好者还是普通用户,这篇文章都将为你揭示两大系统背后的故事和技术细节。 ####
36 0
|
3天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
5天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
7天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
【10月更文挑战第35天】在数字化时代,安卓应用的开发成为了一个热门话题。本文旨在通过浅显易懂的语言,带领初学者了解安卓开发的基础知识,同时为有一定经验的开发者提供进阶技巧。我们将一起探讨如何从零开始构建第一个安卓应用,并逐步深入到性能优化和高级功能的实现。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你提供有价值的指导和灵感。