Android启动流程(Java层)

作者: nick_young | 来源:发表于2017-11-06 18:23 被阅读116次

    写在前面的话

    目前打算是先把Android的启动流程包括luncher、Activity的启动以及Service启动,View的绘制,事件分发等进行分析,后面应该还会包括现阶段正在使用的框架MVVM的分析。可能是更新Android不会太久了,有点迷茫Android的未来到底在哪里,把握现在吧。
    今天这部分讲解的是Android系统启动后加载各种服务的过程。

    1 init

    init是第一个进程,我们可以说它是root进程或者说有进程的父进程。init进程有两个责任,一是挂载目录,比如/sys、/dev、/proc,二是运行init.rc脚本。
    init进程可以在/system/core/init找到。
    init.rc文件可以在/system/core/rootdir/init.rc找到。
    readme.txt可以在/system/core/init/readme.txt找到。
    对于init.rc文件,Android中有特定的格式以及规则。在Android中,我们叫做Android初始化语言。


    2 Zygote加载进程

    Zygote本意是受精卵,Android中可以理解为孵化器。Android的应用的进程都是由Zygote孵化而来,因此他们都有共同的ppid(父进程的id)


    3 SystemServer启动

    Zygote启动完成后,Zygote创建新的进程去启动系统服务。我们都知道Android的进程间通信是通过binder机制,通过binder机制可以避免对某个服务的单独创建,所有的服务在系统启动后即创建完成。但是我们通过Context.getSystemService(String name)获的并不是我们的服务的代理类,我们获取的是各种Manager类。


    3.1 SystemServer启动流程

    打开SystemServer.java ,我们可以看到它是一个含有main方法的类,Zygote启动系统服务时会调用这个main方法。

    public static void main(String[] args) {
        new SystemServer().run();
    }
    

    main创建了SystemServer对象后,调用其run方法,下面是具体实现。

    private void run() {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitBeforeStartServices");
            //进行时间校验
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }
            //语言校验
            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                final String languageTag = Locale.getDefault().toLanguageTag();
    
                SystemProperties.set("persist.sys.locale", languageTag);
                SystemProperties.set("persist.sys.language", "");
                SystemProperties.set("persist.sys.country", "");
                SystemProperties.set("persist.sys.localevar", "");
            }
            
            ......
            //设置线程优先级
            android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            
            //开启了一个Looper用于消息处理,此处和ActivityThread创建消息队列循环一致
            Looper.prepareMainLooper();
            //加载了android_servers.so,里面应该是各个server
            System.loadLibrary("android_servers");
            performPendingShutdown();
            //创建了系统的上下文Context 3.1.1
            createSystemContext();
            //将SystemServiceManager放入LocalServices中
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    
        try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            //启动关键services 3.2
            startBootstrapServices();
            //启动核心services 3.3
            startCoreServices();
            //启动其他services 3.4
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }
        //开启消息队列循环
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    

    run()方法中先对时间和语言进行校验后,创建了一个消息队列,并通过createSystemContext()方法创建SystemServer的上下文对象,之后开始启动引导services,接下来是核心services以及最后启动其他services。


    3.1.1 createSystemContext()过程

    从名字中我们可以知道这个方法是用来创建系统的上下文对象,createSystemContext()中代码比较少,很容易理解。

    private void createSystemContext() {
        //通过ActivityThread的systemMain()进行对象的创建 3.1.2
        ActivityThread activityThread = ActivityThread.systemMain();
        //将上下文对象赋值
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    }
    

    3.1.2 Context创建的过程

    ActivityThread创建的过程,不得不说谷歌的代码真是短小精悍啊。

    public static ActivityThread systemMain() {
        if (!ActivityManager.isHighEndGfx()) {
            ThreadedRenderer.disable(true);
        } else {
            ThreadedRenderer.enableForegroundTrimming();
        }
        //好像注释都不需要了。
        ActivityThread thread = new ActivityThread();
        thread.attach(true);
        return thread;
    }
    

    接着我们来看thread.attach(true)方法。(参数我们传入的是true),这里只展示执行的代码。

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
           ......
        } else {
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            //这句话挺有意思的。。。
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                //创建context
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                //调用Application的onCreate()方法
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }
        DropBox.setReporter(new DropBoxReporter());
    
        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {......});
    }
    
    //对象不重复创建
    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                //创建系统的上下文
                mSystemContext = ContextImpl.createSystemContext(this);
            }
            return mSystemContext;
        }
    }
    

    代码比较简单,通过createAppContext方法创建一个上下文对象,并通过makeApplication方法创建Application,并调用onCreate()方法,最后调用getSystemContext()将上下文赋值给mSystemContext。这边对上下文的创建就到这里结束了,下面开始对各种服务启动的流程分析。


    3.2 startBootstrapServices()启动核心服务

    启动核心服务的过程其实并没有多么的复杂,最开始被启动的是Installer,即系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务,之后启动AMSPowerManagerServiceLightsServiceDisplayManagerService......,核心代码如下:

    private void startBootstrapServices() {
        //系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务
        //直接翻译了源码注释(有点无耻哈)。
        //等待installd完成启动,以便它有机会创建具有适当权限的关键目录,如/ data / user。 
        //在我们初始化其他服务之前,我们需要完成这个工作 startService 3.2.1
        Installer installer = mSystemServiceManager.startService(Installer.class);
        //启动ActivityManagerService
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        //电源管理器需要提前启动,因为其他服务需要它。
        //本地守护进程可能正在注册,因此它必须立即处理传入的绑定器调用(包括能够验证这些调用的权限)。
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
    
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");
        mActivityManagerService.initPowerManagement();
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        //启动灯光service
        mSystemServiceManager.startService(LightsService.class);
        //启动显示service
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
        //在初始化package manager完成前,我们需要默认显示
        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    
        String cryptState = SystemProperties.get("vold.decrypt");
        if (ENCRYPTING_STATE.equals(cryptState)) {
            Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
            mOnlyCore = true;
        } else if (ENCRYPTED_STATE.equals(cryptState)) {
            Slog.w(TAG, "Device encrypted - only parsing core apps");
            mOnlyCore = true;
        }
    
        traceBeginAndSlog("StartPackageManagerService");
        //PackageManagerService开始初始化
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        
        if (!mOnlyCore) {
            boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                    false);
            if (!disableOtaDexopt) {
                traceBeginAndSlog("StartOtaDexOptService");
                try {
                    OtaDexoptService.main(mSystemContext, mPackageManagerService);
                } catch (Throwable e) {
                    reportWtf("starting OtaDexOptService", e);
                } finally {
                    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                }
            }
        }
    
        traceBeginAndSlog("StartUserManagerService");
        //多用户UserManagerService
        mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
        
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        
        AttributeCache.init(mSystemContext);
        //把几个service添加到ServiceManager的中
        mActivityManagerService.setSystemProcess();
        //启动传感器的服务,native方法
        startSensorService();
    }
    

    3.2.1 SystemServiceManager.startService的过程

    启动service的过程比较简单,通过反射去创建service对象,其构造方法的参数为Context,并将其添加到SystemServiceManagermServices列表中。

    /**
     * 通过反射去创建,其构造方法的参数为Context
     */
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {......}
    
            // 添加到mServices列表中
            mServices.add(service);
            try {
                //调用onStart方法
                service.onStart();
            } catch (RuntimeException ex) {......}
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
    

    3.3启动核心服务

    从代码中可以看出核心服务包括了管理电池相关的服务,收集用户使用每一个APP的频率、使用时常的服务以及WebView更新服务的启动。

    private void startCoreServices() {
        //管理电池相关的服务
        mSystemServiceManager.startService(BatteryService.class);
    
        //收集用户使用每一个APP的频率、使用时常
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
    
        //WebView更新服务
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    }
    

    3.4 启动其他服务

    启动其他服务,包括蓝牙,摄像头相关服务,管理输入事件等服务,这里不赘述。

    /**
     * 其他服务,包括蓝牙,摄像头相关服务,管理输入事件等服务,这里不赘述
     */
    private void startOtherServices() {
        ......
        //划重点,这里会启动HomeActivity,下篇讲HomeActivity启动流程,这里mark下
        mActivityManagerService.systemReady(new Runnable() {
           @Override
            public void run() {
                ......
            }
        });
    }
    

    不过,里面有个重要的地方是关于HomeActivity的启动,调用了mActivityManagerService.systemReady(new Runnable()后,会启动HomeActivity,下篇讲解下。


    写在后面的话

    今天的分析好像并没有过多的流程,代码看起来也比较简单,后面的会比较复杂,我会将时序图上传,方便自己以后复习。

    相关文章

      网友评论

        本文标题: Android启动流程(Java层)

        本文链接:https://www.haomeiwen.com/subject/ojzlmxtx.html