日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android:process=.server,Android启动(三)----开启SystemServer进程

發布時間:2025/3/20 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android:process=.server,Android启动(三)----开启SystemServer进程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面已經講到,從C/C++層進入了Java層,即調用了ZygoteInit.main()函數,那么接下來會發生什么事情呢?

源碼參考Android4.1.1,涉及的文件有ZygoteInit.java,RuntimeInit.java(framework文件夾下)

ZygoteInit.main():

public static void main(String argv[]) {

try {

// Start profiling the zygote initialization.

SamplingProfilerIntegration.start();

//創建服務端的socket

registerZygoteSocket();

EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,

SystemClock.uptimeMillis());

// 最終調用preloadClasses();preloadResources();兩個函數,

//加載class文件和res資源

preload();

EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,

SystemClock.uptimeMillis());

// Finish profiling the zygote initialization.

SamplingProfilerIntegration.writeZygoteSnapshot();

// Do an initial gc to clean up after startup

gc();

//這里的argv就是在C層產生的字符串數組,有兩個元素

// If requested, start system server directly from Zygote

if (argv.length != 2) {

throw new RuntimeException(argv[0] + USAGE_STRING);

}

//顯然,條件成立

if (argv[1].equals("start-system-server")) {

//這是要真刀真槍的開啟SS進程了

startSystemServer();

} else if (!argv[1].equals("")) {

throw new RuntimeException(argv[0] + USAGE_STRING);

}

Log.i(TAG, "Accepting command socket connections");

if (ZYGOTE_FORK_MODE) {

runForkMode();

} else {

//這個函數其實也很重要,簡而言之,讓zygote休眠,但是隨時能接受消息

//從loop字眼也可以看出循環的意思,后面的文章會在提到這個

runSelectLoopMode();

}

closeServerSocket();

} catch (MethodAndArgsCaller caller) {

caller.run();

} catch (RuntimeException ex) {

Log.e(TAG, "Zygote died with exception", ex);

closeServerSocket();

throw ex;

}

}

再看看startSystemServer()函數

private static boolean startSystemServer()

throws MethodAndArgsCaller, RuntimeException {

/* Hardcoded command line to start the system server */

String args[] = {//參數

"--setuid=1000",

"--setgid=1000",

"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",

"--capabilities=130104352,130104352",

"--runtime-init",

"--nice-name=system_server",

"com.android.server.SystemServer",

};

ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {

parsedArgs = new ZygoteConnection.Arguments(args);

ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);

ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

/* Request to fork the system server process */

pid = Zygote.forkSystemServer(//fork一個子進程

parsedArgs.uid, parsedArgs.gid,

parsedArgs.gids,

parsedArgs.debugFlags,

null,

parsedArgs.permittedCapabilities,

parsedArgs.effectiveCapabilities);

} catch (IllegalArgumentException ex) {

throw new RuntimeException(ex);

}

/* For child process */

if (pid == 0) {//子進程,即system_server進程

handleSystemServerProcess(parsedArgs);

}

return true;

}

果然看到了forkSystemServer這樣的函數了,接下來在子進程中調用了handleSystemServerProcess()函數:

/**

* Finish remaining work for the newly forked system server process.

*/

private static void handleSystemServerProcess(

ZygoteConnection.Arguments parsedArgs)

throws ZygoteInit.MethodAndArgsCaller {

closeServerSocket();

// set umask to 0077 so new files and directories will default to owner-only permissions.

FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO);

//niceName?

if (parsedArgs.niceName != null) {

Process.setArgV0(parsedArgs.niceName);

}

if (parsedArgs.invokeWith != null) {

WrapperInit.execApplication(parsedArgs.invokeWith,

parsedArgs.niceName, parsedArgs.targetSdkVersion,

null, parsedArgs.remainingArgs);

} else {

/*

* Pass the remaining arguments to SystemServer.

*/

//顯然就是這個函數最重要了,

RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);

}

}

需要注意的是zygoteInit()函數是RuntimeInit類直接調用的,說明它是靜態函數,在RuntimeInit.java文件中,zygoteInit()函數如下:

/**

* The main function called when started through the zygote process. This

* could be unified with main(), if the native code in nativeFinishInit()

* were rationalized with Zygote startup.

*

* Current recognized args:

*

*

[--]

*

*

* @param targetSdkVersion target SDK version

* @param argv arg strings

*/

public static final void zygoteInit(int targetSdkVersion, String[] argv)

throws ZygoteInit.MethodAndArgsCaller {

if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

redirectLogStreams();

commonInit();

//本地zygoteInit函數,主要職責是C++層的初始化

nativeZygoteInit();

//另外的一些初始化工作

applicationInit(targetSdkVersion, argv);

}

本地的zygoteInit函數我們先放在一邊,先看applicationInit函數:

private static void applicationInit(int targetSdkVersion, String[] argv)

throws ZygoteInit.MethodAndArgsCaller {

// If the application calls System.exit(), terminate the process

// immediately without running any shutdown hooks. It is not possible to

// shutdown an Android application gracefully. Among other things, the

// Android runtime shutdown hooks close the Binder driver, which can cause

// leftover running threads to crash before the process actually exits.

nativeSetExitWithoutCleanup(true);

// We want to be fairly aggressive about heap utilization, to avoid

// holding on to a lot of memory that isn't needed.

VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);

VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

final Arguments args;

try {

//一些參數設定

args = new Arguments(argv);

} catch (IllegalArgumentException ex) {

Slog.e(TAG, ex.getMessage());

// let the process exit

return;

}

// Remaining arguments are passed to the start class's static main

//英文解釋的其實已經比較明白了,

invokeStaticMain(args.startClass, args.startArgs);

}

再來看看invokeStaticMain函數,很明顯,調用了JNI.

private static void invokeStaticMain(String className, String[] argv)

throws ZygoteInit.MethodAndArgsCaller {

Class> cl;

try {

//獲取類對象

cl = Class.forName(className);

} catch (ClassNotFoundException ex) {

throw new RuntimeException(

"Missing class when invoking static main " + className,

ex);

}

Method m;

try {

//獲取方法

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);

}

int modifiers = m.getModifiers();

if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {

throw new RuntimeException(

"Main method is not public and static on " + className);

}

/*

* 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.

*/

throw new ZygoteInit.MethodAndArgsCaller(m, argv);

##居然主動拋出異常?!!,what‘s the shit?

}

好吧,我在手心連寫十個“忍”,繼續還是心平氣和的看代碼,其實只要往上追溯,由于上層的方法都選擇拋出該異常,最終追溯到了ZygoteInit.main()方法中,

在回顧main函數(部分):

try {

.........

.........

.........

if (argv[1].equals("start-system-server")) {

startSystemServer();

} else if (!argv[1].equals("")) {

throw new RuntimeException(argv[0] + USAGE_STRING);

}

Log.i(TAG, "Accepting command socket connections");

if (ZYGOTE_FORK_MODE) {

runForkMode();

} else {

runSelectLoopMode();

}

closeServerSocket();

} catch (MethodAndArgsCaller caller) {

##shit!!,在這里catch到了這個異常,看來是有意為之了

caller.run();

} catch (RuntimeException ex) {

Log.e(TAG, "Zygote died with exception", ex);

closeServerSocket();

throw ex;

}

好,caller對象是(MethodAndArgsCaller類型的,繼續看caller.run()做了什么:

......

......

public void run() {

try {

##kidding me ??!!,在這里調用了SystemServer.main()方法?

mMethod.invoke(null, new Object[] { mArgs });

//有興趣的同學可以研究一下mArgs里面都是些什么

} 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);

}

}

問題到這里可以說結束了,最終(fork的子進程)調用了SystemServer.main()函數,相當于創造了SystemS進程。

那么問題來了,為什么不在主動拋出異常的的地方直接調用main方法?

說實話,我不是很理解,但是看了鄧平凡大大的《深入理解Android I》(是本好書,值得推薦),里面給出了一種解釋那就是釋放堆棧中被浪費的資源。

稍微解釋一下,就是函數的調用是需要利用調用堆棧來實現的,每調用一個函數,原來的函數的資源會被壓入棧,如果嵌套調用的函數多了的話,會占用系統資源。而關鍵在于SystemServer進程是不會死的(如果死了的話,系統也掛掉了),所以,也就意味著在這之前占用的那些資源不會被釋放,so.......

多說一句,這種方式似乎達成了exec的函數調用的效果,上一篇文章提到,fork往往和exec一起用,可以造就兩個不同的進程,但是實際上exec系統調用的工作原理是替換原來的進程的執行內容,只保留進程ID,可以說exec系統調用會擦除之前的進程積壓的資源,這種拋異常的方式從某種程度上來講實現了exec的效果。

總結

以上是生活随笔為你收集整理的android:process=.server,Android启动(三)----开启SystemServer进程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。