Android 8.0系統啓動流程_SystemServer(三)

本系列主要介紹Android8.0系統啓動過程當中涉及到的initZygote、SystemServer和Launcher。 SystemServer 進程主要用於建立系統服務,像AMS、WMS和PMS等,都是由其建立。java

1、啓動SyetmServer進程

在這裏插入圖片描述
Android 8.0系統啓動流程_Zygote(二)中講解到在ZygoteInit中主要做用是啓動SystemServer進程,源碼以下:

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
...
if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }
...

private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
            ...
	 if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }
        return null;
}
}
複製代碼

因爲SystemServer是複製Zygote的進程,所以也會包含Zygote的socket,該socket是服務端socket,對於SystemServer沒有其餘做用,須要先將其關閉;經過handleSystemServerProcess開啓SystemServer進程。android

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
	...
	ClassLoader cl = null;
            if (systemServerClasspath != null) {
            //建立PathClassLoader
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
                Thread.currentThread().setContextClassLoader(cl);
            }
            //初始化zygoteInit
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
            ...
}

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
...
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();
        RuntimeInit.commonInit();
        //啓動Binder線程池
        ZygoteInit.nativeZygoteInit();
        //執行SystemServer的main方法		
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
複製代碼

啓動Binder線程池是便於SystemServer與其餘進程執行通訊操做; 在調用SystemServer的main方法,相對比較複雜,以前版本是經過RuntimeInit經過拋出MethodAndArgsCaller方式跳轉至ZygoteInit的main方法中,但在8.0中發現是經過建立MethodAndArgsCaller方式,但最終是執行至MethodAndArgsCaller的invoke中,實現SystemServer運行。流程以下:bash

frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
 protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
... 
        return findStaticMain(args.startClass, args.startArgs, classLoader);
}

private static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
 try {
 		//經過反射,獲取SystemServer類,
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }
        
        Method m;
        try {
        //經過反射,獲取SystemServer類的main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }
        ...
       
         /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement * clears up all the stack frames that were required in setting * up the process. */ //本版本中,是直接調製至RuntimeInit的靜態內部類中。 return new MethodAndArgsCaller(m, argv); } 複製代碼

在經過反射獲取SystemServer類時,是如何肯定該傳入的className就是SystemServer?這是因爲在上面的ZygoteInit的mian方法時,對於啓動的進程作了判斷(Zyogte、SystemServer仍是application?),上面部分已明確描述加載的是SystemServer類。app

cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
複製代碼
static class MethodAndArgsCaller implements Runnable {
...
 public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {    
...
}
複製代碼

以上過程完成了從Zygote通過RuntimeInit最後完成SystemServer的main方法的運行。下面重點分析SystemServer的main方法。socket

2、解析SystemServer的main方法

frameworks\base\services\java\com\android\server\SystemServer.java
 public static void main(String[] args) {
        new SystemServer().run();
    }
   private void run() {
        try {
        	//建立Looper對象
            Looper.prepareMainLooper();
            // 加載系統聲明週期管理的servers的庫
            System.loadLibrary("android_servers");
            performPendingShutdown();
            //建立系統的Context
            createSystemContext()
			mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
		SystemServerInitThreadPool.get();
		} finally {
            traceEnd();  // InitBeforeStartServices
        }
  try {
            traceBeginAndSlog("StartServices");
            //啓動引導服務
            startBootstrapServices();
            //啓動核心服務
            startCoreServices();
            //啓動其餘服務
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            throw ex;
        } finally {
            traceEnd();
        }
}

複製代碼

該過程主要的做用是啓動三種服務(引導、核心和其餘服務),分別是指:oop

  • 引導:AMS(ActivityManagerService)、PMS(PackageManagerService)和UMS(UserManagerService)等;
  • 核心:BatterService、UsageStateService和WebViewService等;
  • 其餘: CameraService、InputManagerService和AudioService等。

這些系統服務均來自於ServeryService,可是須要注意在應用層建立的Service不直接屬於ServeryService,由於其不是系統服務,其是經過AMS來 管理控制的。post

相關文章
相關標籤/搜索