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启动方式

相关文章
|
1月前
|
人工智能 搜索推荐 物联网
Android系统版本演进与未来展望####
本文深入探讨了Android操作系统从诞生至今的发展历程,详细阐述了其关键版本迭代带来的创新特性、用户体验提升及对全球移动生态系统的影响。通过对Android历史版本的回顾与分析,本文旨在揭示其成功背后的驱动力,并展望未来Android可能的发展趋势与面临的挑战,为读者呈现一个既全面又具深度的技术视角。 ####
|
27天前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
15天前
|
监控 Java Android开发
深入探索Android系统的内存管理机制
本文旨在全面解析Android系统的内存管理机制,包括其工作原理、常见问题及其解决方案。通过对Android内存模型的深入分析,本文将帮助开发者更好地理解内存分配、回收以及优化策略,从而提高应用性能和用户体验。
|
16天前
|
存储 安全 Android开发
探索Android系统的最新安全特性
在数字时代,智能手机已成为我们生活中不可或缺的一部分。随着技术的不断进步,手机操作系统的安全性也越来越受到重视。本文将深入探讨Android系统最新的安全特性,包括其设计理念、实施方式以及对用户的影响。通过分析这些安全措施如何保护用户免受恶意软件和网络攻击的威胁,我们希望为读者提供对Android安全性的全面了解。
|
1月前
|
监控 Java Android开发
深入探讨Android系统的内存管理机制
本文将深入分析Android系统的内存管理机制,包括其内存分配、回收策略以及常见的内存泄漏问题。通过对这些方面的详细讨论,读者可以更好地理解Android系统如何高效地管理内存资源,从而提高应用程序的性能和稳定性。
66 16
|
22天前
|
安全 Android开发 iOS开发
深入探讨Android与iOS系统的差异及未来发展趋势
本文旨在深入分析Android和iOS两大移动操作系统的核心技术差异、用户体验以及各自的市场表现,进一步探讨它们在未来技术革新中可能的发展方向。通过对比两者的开放性、安全性、生态系统等方面,本文揭示了两大系统在移动设备市场中的竞争态势和潜在变革。
|
1月前
|
算法 JavaScript Android开发
|
27天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
14天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
40 19
|
15天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
41 14