• 源码级分析Android系统启动流程


    首先看一下Android系统的体系结构,相信大家都不陌生

    1.首先Bootloader引导程序启动完Linux内核后,会加载各种驱动和数据结构,当有了驱动以后,开始启动Android系统,同时会加载用户级别的第一个进程init(systemcoreinit.c),该进程会首先加载一个init.rc配置文件,代码如下

    int main(int argc, char **argv)
        {
            
            // 创建文件夹 挂载
            mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");
            mkdir("/dev/pts", 0755);
           
            // 打开日志
            log_init();
            
            INFO("reading config file
    ");
            // 加载init.rc配置文件
            init_parse_config_file("/init.rc");
        
        } 
    

    2.init.rc配置文件会进行很多的配置,创建很多的文件夹及文件,然后初始化一些Android驱动器,之后该配置文件最重要的一个任务就是启动一个Zygote(孵化器)进程,此进程是Android系统的一个母进程,用来启动Android的其他服务进程,代码:

        service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
        socket zygote stream 666
        onrestart write /sys/android_power/request_state wake
        onrestart write /sys/power/state on
        onrestart restart media
        onrestart restart netd
    

    3. Zygote会执行一个app_process可执行文件,在这个文件中首先添加了Android运行时环境,在Android运行时中调用了ZygoteInit.java,这就从c++代码跳到了java代码。

            int main(int argc, const char* const argv[])
        {
            ...
            // Android运行时环境
            AppRuntime runtime;
            ...
            // Next arg is startup classname or "--zygote"
            if (i < argc) {
                arg = argv[i++];
                if (0 == strcmp("--zygote", arg)) {
                    bool startSystemServer = (i < argc) ? 
                            strcmp(argv[i], "--start-system-server") == 0 : false;
                    setArgv0(argv0, "zygote");
                    set_process_name("zygote");
                    // 启动java代码
                    runtime.start("com.android.internal.os.ZygoteInit",
                 ...
        
        }
    

    4.在ZytofeInit.java代码中首先设置了Java虚拟机的堆内存空间,然后启动一个类加载器加载Android启动依赖的类比如Activity等四大组件,dialog等UI的类,然后分出一个子进程启动SystemServer系统服务

      public static void main(String argv[]) {
            try {
                VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);
    
                // 加载Android依赖的类
                preloadClasses();
                //cacheRegisterMaps();
                preloadResources();
                ...
    
                if (argv[1].equals("true")) {
                    // 启动系统服务
                    startSystemServer();
                } else if (!argv[1].equals("false")) {
               ...
        }
    
    
        private static boolean startSystemServer()
             ...
                args = new String[] {
                    "--setuid=1000",
                    "--setgid=1000",
                    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
                    "--capabilities=130104352,130104352",
                    "--rlimit=8,",
                    "--runtime-init",
                    "--nice-name=system_server",
                    "com.android.server.SystemServer",
              ...
    
                /* Request to fork the system server process */
                // 母进程开始分叉服务 启动SystemServer
                pid = Zygote.forkSystemServer(
                        parsedArgs.uid, parsedArgs.gid,
                        parsedArgs.gids, debugFlags, rlimits,
                        parsedArgs.permittedCapabilities,
                        parsedArgs.effectiveCapabilities);
            ...
        }
    

    5.在SystemServer.java代码中有两个方法init1()启动Native世界,init2()启动Android的Framework世界

        public static void main(String[] args) {
               ... 
            // 加载jni库
            System.loadLibrary("android_servers");
            // 调用native方法,该方法启动Native世界
            init1(args);
        }
        native public static void init1(String[] args);
    

    6.SystemServer首先调用init1()方法加载JNI库,启动Native世界。init1通过System.loadLibrary("android-servers")加载一个类库文件,其对应的源码文件为com_android_server_SystemServer.cpp 其C++代码如下,在该类库中转调了system_init()方法

        // 类似java的抽象方法
        extern "C" int system_init();
        
        static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
        {    
            // 转调
            system_init();
        }
        
        /*
         * JNI registration.
         */
        static JNINativeMethod gMethods[] = {
            /* name, signature, funcPtr */ 
            // 函数指针 把init1方法映射到android_server_SystemServer_init1
            { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
        };
    

    7.System_init方法在System_init.cpp中实现,它首先启动系统的硬件服务,比如Audio、Camera等,启动完硬件服务后它又通过Android运行时环境调用了SystemServer中的init2()方法,init2()方法启动Framework世界,代码如下:

        extern "C" status_t system_init()
        {
            ...
            // 启动硬件的服务
            if (strcmp(propBuf, "1") == 0) {
                // Start the SurfaceFlinger
                SurfaceFlinger::instantiate();
            }
        
            
            
            AndroidRuntime* runtime = AndroidRuntime::getRuntime();
        
            LOGI("System server: starting Android services.
    ");
            // 启动完硬件服务后,又回到Systemserver的init2方法
            runtime->callStatic("com/android/server/SystemServer", "init2");
            ...
        }
    

    8.SystemServer的init2方法,init2()方法启动Android的Framework层,启动Android世界。在该方法中启动了一个ServerThread线程,其代码如下:

        public static final void init2() {
                Slog.i(TAG, "Entered the Android system server!");
                Thread thr = new ServerThread();
                thr.setName("android.server.ServerThread");
                thr.start();
            }
    

    9.init2()启动的线程ServerThread中的的run方法中通过一个Looper开启了Android中的各种服务比如LightService,PowerManagerService,BatteryService,WindowManagerService等,并将服务添加到ServiceManager中去管理,启动完各种服务后,调用ActivityManagerService.systemReady方法:

     public void run() {
            ...
            // 开启Android各种服务并且添加到ServiceManager去管理
            Slog.i(TAG, "Device Policy");
            devicePolicy = new DevicePolicyManagerService(context);
            ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, ottle = 
    
            ...
            // We now tell the activity manager it is okay to run third party
            // code.  It will call back into us once it has gotten to the state
            // where third party code can really run (but before it has actually
            // started launching the initial applications), for us to complete our
            // initialization.
            // 各种服务开启后调用ActivityManagerService.systemReady
            ((ActivityManagerService)ActivityManagerNative.getDefault())
                    .systemReady(new Runnable() {
                public void run() {
                    Slog.i(TAG, "Making services ready");
    

    10.在ActivityManagerService的systemReady方法中打开Android系统的第一个Activity

        public void systemReady(final Runnable goingCallback) {
                ...
                // 打开第一个Activity
                    mMainStack.resumeTopActivityLocked(null);
                }
            }
    

    11.ActivityStack的resumeTopActivityLocked方法启动home界面

        final boolean resumeTopActivityLocked(ActivityRecord prev) {
                // Find the first activity that is not finishing.
                // 没有已经打开的Activity, next为 null
                ActivityRecord next = topRunningActivityLocked(null);
        
                // Remember how we'll process this pause/resume situation, and ensure
                // that the state is reset however we wind up proceeding.
                final boolean userLeaving = mUserLeaving;
                mUserLeaving = false;
        
                if (next == null) {
                    // There are no more activities!  Let's just start up the
                    // Launcher...
    
                    if (mMainStack) {
                        // 启动lucher应用的锁屏界面
                        return mService.startHomeActivityLocked();
                    }
                }
    

    12.打开了Luncher应用的Home界面之后,到此Android系统启动完成了。

    可以把整个过程总结为如下这张图

  • 相关阅读:
    基于NPOI的报表引擎——ExcelReport
    XML数据源快速开发框架——XmlFramwork
    SqlExcel使用文档及源码
    第三篇:属性_第二节:控件属性在页面及源码中的表示方式
    第三篇:属性_第一节:控件属性与属性的持久化
    第二篇:呈现内容_第四节:个性化自定义控件
    第二篇:呈现内容_第三节:CompositeControl呈现
    Web用户控件开发--星型评分控件
    iOS 统计Xcode整个工程的代码行数
    iOS开发中的火星坐标系及各种坐标系转换算法
  • 原文地址:https://www.cnblogs.com/rocomp/p/5001639.html
Copyright © 2020-2023  润新知