Android 시스템 시작(3) - SystemServer 프로세스

system_server프로세스는 주로 시스템 서비스를 생성하는 데 사용되며 , AMS모두 생성됩니다. WMSPMS구체적으로 SystemServer프로세스가 생성된 후 주로 다음 작업을 수행합니다.

  • Binder다른 프로세스와 통신할 수 있도록 스레드 풀을 시작합니다 .
  • 생성 SystemServiceManager, 시스템 서비스의 수명 주기를 생성, 시작 및 관리하는 데 사용됩니다.
  • 다양한 시스템 서비스를 시작하십시오.

1 Zygote가공 system_server공정

Zygote 프로세스 시작 프로세스 에서 언급한 것처럼 ZygoteInit.main메서드 에서 프로세스는 일부 관련 타이밍 다이어그램인 forkSystemServer메서드를 호출하여 시작됩니다 .system_server

그림 1

ZygoteInit.forkSystemServer코드는 다음과 같습니다.

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName, 
                                         ZygoteServer zygoteServer) {
    
    
    ...
    /* For child process 当前运行在 system_server 进程中 */
    if (pid == 0) {
    
    
        if (hasSecondZygote(abiList)) {
    
    
            waitForSecondaryZygote(socketName);
        }
		// 关闭 Zygote 进程创建的 Socket
        zygoteServer.closeServerSocket(); // 1
        return handleSystemServerProcess(parsedArgs); // 2
    }

    return null;
}

system_server프로세스는 프로세스의 주소 공간을 복사하므로 프로세스에 의해 생성 Zygote되므로 프로세스 사용되지 않으므로 주석 에서 닫아야 합니다 . ZygoteSocketSocketsystem_server1Socket다음으로 주석에서 메서드를 2호출하여 프로세스를 시작합니다. 메서드의 코드는 다음과 같습니다.handleSystemServerProcesssystem_serverhandleSystemServerProcess

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    
    
    ...
    if (parsedArgs.mInvokeWith != null) {
    
    
        ...
    } else {
    
    
        createSystemServerClassLoader(); // 1
        ClassLoader cl = sCachedSystemServerClassLoader;
        if (cl != null) {
    
    
            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         */
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                                     parsedArgs.mRemainingArgs, cl); // 2
    }
}

private static void createSystemServerClassLoader() {
    
    
    if (sCachedSystemServerClassLoader != null) {
    
    
        return;
    }
    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    // TODO: Should we run optimization here?
    if (systemServerClasspath != null) {
    
    
        sCachedSystemServerClassLoader = createPathClassLoader(
            systemServerClasspath, VMRuntime.SDK_VERSION_CUR_DEVELOPMENT);
    }
}

댓글에서 1생성되었습니다 ClassLoader. 메소드는 주석에서 2호출되며 ZygoteInit.zygoteInit코드는 다음과 같습니다.

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
                                        ClassLoader classLoader) {
    
    
    if (RuntimeInit.DEBUG) {
    
    
        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    RuntimeInit.redirectLogStreams();

    RuntimeInit.commonInit();
    // 启动 Binder 线程池
    ZygoteInit.nativeZygoteInit(); // 1
    // 进入 system_server 的 main 方法
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); // 2
}

프로세스가 다른 프로세스와 통신하는 데 사용할 수 있도록 스레드 풀을 시작하기 위해 레이어의 코드가 호출되는 주석 1에서 메서드를 호출합니다 . 주석은 를 입력하는 데 사용되는 방법입니다 .ZygoteInit.nativeZygoteInitNativeBindersystem_serverBinder2system_servermain

아래에서 묘사 되어진

Binder1 스레드 풀 시작

ZygoteInit.nativeZygoteInit()이 메서드인 경우 먼저 다음과 같이 Native해당 파일을 이해해야 합니다 .JNI

// /frameworks/base/core/jni/AndroidRuntime.cpp
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
    
    
    const JNINativeMethod methods[] = {
    
    
        {
    
     "nativeZygoteInit", "()V",
         (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
                                    methods, NELEM(methods));
}

JNI의 배열을 통해 메소드가 파일 의 기능에 해당함 methods을 알 수 있습니다 .nativeZygoteInitJNIAndroidRuntime.cppcom_android_internal_os_ZygoteInit_nativeZygoteInit

// /frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    
    
    gCurRuntime->onZygoteInit();
}

gCurRuntime특히 의 하위 클래스를 가리키고 에 정의된 AndroidRuntime유형의 포인터 입니다 . 다음으로 메서드를 보면 코드는 다음과 같습니다.AndroidRuntimeAppRuntimeapp_main.cppAppRuntime.onZygoteInit

// /frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
    
    
    sp<ProcessState> proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool(); // 1
}

comment 의 코드는 프로세스가 다른 프로세스와 통신하는 데 사용할 수 있도록 스레드 풀을 1시작하는 데 사용됩니다 . 따라서 여기에서 이 함수가 주로 쓰레드 풀을 시작하는 데 사용된다는 것을 알 수 있습니다.Bindersystem_serverBinderZygoteInit.nativeZygoteInit()Binder

2 액세스 SystemServer.main방법

RuntimeInit.applicationInit메서드의 소스 코드 보기 :

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
                                          ClassLoader classLoader) {
    
    
    ...
    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

메서드는 주로 다음 메서드 RuntimeInit.applicationInit에서 호출됩니다 findStaticMain.

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
                                         ClassLoader classLoader) {
    
    
    Class<?> cl;

    try {
    
    
        // 通过反射得到 SystemServer 类
        cl = Class.forName(className, true, classLoader); // 1
    } 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 }); // 2
    } 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);
    }

    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
    
    
        throw new RuntimeException(
            "Main method is not public and static on " + className);
    }

    
    return new MethodAndArgsCaller(m, argv); // 3
}

주석 1의 는 className이고 com.android.server.SystemServer리플렉션에 의해 반환된 것은 클래스 cl입니다 . SystemServer주석에서 방법을 2찾으십시오 SystemServer.main. 주석에서 3찾은 main메서드를 MethodAndArgsCaller에 전달합니다.

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
    
    
    ...
    try {
    
    
        ...
        if (startSystemServer) {
    
    
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the child (system_server) process.
            if (r != null) {
    
    
                r.run(); // 1
                return;
            }
        }
        ...
    } catch (Throwable ex) {
    
    
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
    
    
        if (zygoteServer != null) {
    
    
            zygoteServer.closeServerSocket();
        }
    }
	...
}

1주석의 코드 에서 우리는 객체가 ZygoteInit.main메소드에서 얻어지고 메소드가 MethodAndArgsCaller호출 MethodAndArgsCaller.run()된다는 것을 알 수 있습니다. 다음의 정적 내부 클래스 MethodAndArgsCaller입니다 .Zygote

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
static class MethodAndArgsCaller implements Runnable {
    
    
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
    
    
        mMethod = method;
        mArgs = args;
    }

    public void run() {
    
    
        try {
    
    
            mMethod.invoke(null, new Object[] {
    
     mArgs }); // 1
        } catch (IllegalAccessException ex) {
    
    
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
    
    
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
    
    
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
    
    
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

주석 1의 는 메서드를 mMethod의미하며 메서드가 호출된 메서드도 동적으로 호출됩니다.SystemServer.mainmMethod.invokeSystemServer.main

2 파싱 system_server프로세스

SystemServer.main방법은 다음과 같습니다 .

// /frameworks/base/services/java/com/android/server/SystemServer.java 
public static void main(String[] args) {
    
    
    new SystemServer().run();
}

메소드에서만 메소드 SystemServer.main가 호출됩니다 SystemServer().run().

// /frameworks/base/services/java/com/android/server/SystemServer.java 
private void run() {
    
    
    try {
    
    
        ...
        // 创建消息 Looper
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
            SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        // Initialize native services. 加载了动态库 libandroid_servers.so
        System.loadLibrary("android_servers"); // 1
		...
        // Initialize the system context. 创建系统的 Context
        createSystemContext();

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext); // 2
        mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, 
                                           mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        SystemServerInitThreadPool.get();
    } finally {
    
    
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
    try {
    
    
        traceBeginAndSlog("StartServices");
        startBootstrapServices(); // 3 启动引导服务
        startCoreServices(); // 4 启动核心服务
        startOtherServices(); // 5 启动其他服务
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
    
    
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
    
    
        traceEnd();
    }

    ...
    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

주석에 1동적 라이브러리가 로드됩니다 libandroid_servers.so. 주석으로 2생성된 SystemServiceManager그녀는 시스템 서비스를 생성, 시작 및 수명 주기 관리합니다. 3주석 에 있는 메서드 에서 start , 등의 서비스를 재사용 startBootstrapServices()합니다 . 주석 의 메서드에서 , , 및 를 시작합니다 . , 등의 서비스는 주석 처리된 메서드 에서 시작됩니다 .SystemServiceManagerActivityManagerServicePowerManagerServicePackageManagerService4startCoreServices()DropBoxManagerServiceBatteryServiceUsageStateServiceWebViewUpdateService5startOtherServices()CameraServiceAlarmManagerServiceVrManagerService

공식 시스템 서비스는 부팅 서비스, 핵심 서비스 및 기타 서비스의 세 3가지 유형으로 나뉘며 , 그 중 다른 서비스 4즉시 시작할 필요가 없는 중요하지 않은 서비스입니다. 총 여러 시스템 서비스가 있으며 그 중 일부는 다음과 같습니다.5100

그림 2

Supongo que te gusta

Origin blog.csdn.net/xingyu19911016/article/details/128619982
Recomendado
Clasificación