1. 程式人生 > >Android系統程序Zygote啟動過程的原始碼分析

Android系統程序Zygote啟動過程的原始碼分析

        在Android系統中,所有的應用程式程序以及系統服務程序SystemServer都是由Zygote程序孕育(fork)出來的,這也許就是為什麼要把它稱為Zygote(受精卵)的原因吧。由於Zygote程序在Android系統中有著如此重要的地位,本文將詳細分析它的啟動過程。

《Android系統原始碼情景分析》一書正在進擊的程式設計師網(http://0xcc0xcd.com)中連載,點選進入!

        在前面一篇文章Android應用程式程序啟動過程的原始碼分析中,我們看到了,當ActivityManagerService啟動一個應用程式的時候,就會通過Socket與Zygote程序進行通訊,請求它fork一個子程序出來作為這個即將要啟動的應用程式的程序;在前面兩篇文章

Android應用程式安裝過程原始碼分析Android系統預設Home應用程式(Launcher)的啟動過程原始碼分析中,我們又看到了,系統中的兩個重要服務PackageManagerService和ActivityManagerService,都是由SystemServer程序來負責啟動的,而SystemServer程序本身是Zygote程序在啟動的過程中fork出來的。

        我們知道,Android系統是基於Linux核心的,而在Linux系統中,所有的程序都是init程序的子孫程序,也就是說,所有的程序都是直接或者間接地由init程序fork出來的。Zygote程序也不例外,它是在系統啟動的過程,由init程序建立的。在系統啟動指令碼system/core/rootdir/init.rc檔案中,我們可以看到啟動Zygote程序的指令碼命令:

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
        前面的關鍵字service告訴init程序建立一個名為"zygote"的程序,這個zygote程序要執行的程式是/system/bin/app_process,後面是要傳給app_process的引數。

        接下來的socket關鍵字表示這個zygote程序需要一個名稱為"zygote"的socket資源,這樣,系統啟動後,我們就可以在/dev/socket目錄下看到有一個名為zygote的檔案。這裡定義的socket的型別為unix domain socket,它是用來作本地程序間通訊用的,具體可以參考前面一篇文章

Android學習啟動篇提到的一書《Linux核心原始碼情景分析》的第七章--基於socket的程序間通訊。前面我們說到的ActivityManagerService就是通這個socket來和zygote程序通訊請求fork一個應用程式程序的了。

        最後的一系列onrestart關鍵字表示這個zygote程序重啟時需要執行的命令。

        關於init.rc檔案的更多資訊,請參考system/core/init/readme.txt檔案。

        瞭解了這個資訊之後,我們就知道Zygote程序要執行的程式便是system/bin/app_process了,它的原始碼位於frameworks/base/cmds/app_process/app_main.cpp檔案中,入口函式是main。在繼續分析Zygote程序啟動的過程之前,我們先來看看它的啟動序列圖:


        下面我們就詳細分析每一個步驟。

        Step 1. app_process.main

        這個函式定義在frameworks/base/cmds/app_process/app_main.cpp檔案中:

int main(int argc, const char* const argv[])
{
	// These are global variables in ProcessState.cpp
	mArgC = argc;
	mArgV = argv;

	mArgLen = 0;
	for (int i=0; i<argc; i++) {
		mArgLen += strlen(argv[i]) + 1;
	}
	mArgLen--;

	AppRuntime runtime;
	const char *arg;
	argv0 = argv[0];

	// Process command line arguments
	// ignore argv[0]
	argc--;
	argv++;

	// Everything up to '--' or first non '-' arg goes to the vm

	int i = runtime.addVmArguments(argc, argv);

	// Next arg is parent directory
	if (i < argc) {
		runtime.mParentDir = argv[i++];
	}

	// 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");
			runtime.start("com.android.internal.os.ZygoteInit",
				startSystemServer);
		} else {
			set_process_name(argv0);

			runtime.mClassName = arg;

			// Remainder of args get passed to startup class main()
			runtime.mArgC = argc-i;
			runtime.mArgV = argv+i;

			LOGV("App process is starting with pid=%d, class=%s.\n",
				getpid(), runtime.getClassName());
			runtime.start();
		}
	} else {
		LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
		fprintf(stderr, "Error: no class name or --zygote supplied.\n");
		app_usage();
		return 10;
	}

}
        這個函式的主要作用就是建立一個AppRuntime變數,然後呼叫它的start成員函式。AppRuntime這個類我們在Android應用程式程序啟動過程的原始碼分析一文中已經有過介紹了,它同樣是在frameworks/base/cmds/app_process/app_main.cpp檔案中定義:
class AppRuntime : public AndroidRuntime
{
	......
};
        它約繼承於AndroidRuntime類, AndroidRuntime類定義在frameworks/base/core/jni/AndroidRuntime.cpp檔案中:
......

static AndroidRuntime* gCurRuntime = NULL;

......

AndroidRuntime::AndroidRuntime()
{
	......

	assert(gCurRuntime == NULL);        // one per process
	gCurRuntime = this;
}
        當AppRuntime物件建立時,會呼叫其父類AndroidRuntime的建構函式,而在AndroidRuntime類的建構函式裡面,會將this指標儲存在靜態全域性變數gCurRuntime中,這樣,當其它地方需要使用這個AppRuntime物件時,就可以通過同一個檔案中的這個函式來獲取這個物件的指標:
AndroidRuntime* AndroidRuntime::getRuntime()
{
    return gCurRuntime;
}
        回到上面的main函式中,由於我們在init.rc檔案中,設定了app_process啟動引數--zygote和--start-system-server,因此,在main函式裡面,最終會執行下面語句:
    runtime.start("com.android.internal.os.ZygoteInit",
	startSystemServer);
        這裡的引數startSystemServer為true,表示要啟動SystemServer元件。由於AppRuntime沒有實現自己的start函式,它繼承了父類AndroidRuntime的start函式,因此,下面會執行AndroidRuntime類的start函式。

        Step 2. AndroidRuntime.start

        這個函式定義在frameworks/base/core/jni/AndroidRuntime.cpp檔案中:

/*
* Start the Android runtime.  This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*/
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
	......

	char* slashClassName = NULL;
	char* cp;
	JNIEnv* env;

	......

	/* start the virtual machine */
	if (startVm(&mJavaVM, &env) != 0)
		goto bail;

	/*
	* Register android functions.
	*/
	if (startReg(env) < 0) {
		LOGE("Unable to register all android natives\n");
		goto bail;
	}

	/*
	* We want to call main() with a String array with arguments in it.
	* At present we only have one argument, the class name.  Create an
	* array to hold it.
	*/
	jclass stringClass;
	jobjectArray strArray;
	jstring classNameStr;
	jstring startSystemServerStr;
	stringClass = env->FindClass("java/lang/String");
	assert(stringClass != NULL);
	strArray = env->NewObjectArray(2, stringClass, NULL);
	assert(strArray != NULL);
	classNameStr = env->NewStringUTF(className);
	assert(classNameStr != NULL);
	env->SetObjectArrayElement(strArray, 0, classNameStr);
	startSystemServerStr = env->NewStringUTF(startSystemServer ?
		"true" : "false");
	env->SetObjectArrayElement(strArray, 1, startSystemServerStr);

	/*
	* Start VM.  This thread becomes the main thread of the VM, and will
	* not return until the VM exits.
	*/
	jclass startClass;
	jmethodID startMeth;

	slashClassName = strdup(className);
	for (cp = slashClassName; *cp != '\0'; cp++)
		if (*cp == '.')
			*cp = '/';

	startClass = env->FindClass(slashClassName);
	if (startClass == NULL) {
		......
	} else {
		startMeth = env->GetStaticMethodID(startClass, "main",
			"([Ljava/lang/String;)V");
		if (startMeth == NULL) {
			......
		} else {
			env->CallStaticVoidMethod(startClass, startMeth, strArray);
			......
		}
	}

	......
}

        這個函式的作用是啟動Android系統執行時庫,它主要做了三件事情,一是呼叫函式startVM啟動虛擬機器,二是呼叫函式startReg註冊JNI方法,三是呼叫了com.android.internal.os.ZygoteInit類的main函式。

        Step 3. ZygoteInit.main

        這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:

public class ZygoteInit {
	......

	public static void main(String argv[]) {
		try {
			......

			registerZygoteSocket();
			
			......

			......

			if (argv[1].equals("true")) {
				startSystemServer();
			} else if (!argv[1].equals("false")) {
				......
			}

			......

			if (ZYGOTE_FORK_MODE) {
				......
			} else {
				runSelectLoopMode();
			}

			......
		} catch (MethodAndArgsCaller caller) {
			......
		} catch (RuntimeException ex) {
			......
		}
	}

	......
}
         它主要作了三件事情,一個呼叫registerZygoteSocket函式建立了一個socket介面,用來和ActivityManagerService通訊,二是呼叫startSystemServer函式來啟動SystemServer元件,三是呼叫runSelectLoopMode函式進入一個無限迴圈在前面建立的socket介面上等待ActivityManagerService請求建立新的應用程式程序。

         Step 4. ZygoteInit.registerZygoteSocket

         這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:

public class ZygoteInit {
	......

	/**
	* Registers a server socket for zygote command connections
	*
	* @throws RuntimeException when open fails
	*/
	private static void registerZygoteSocket() {
		if (sServerSocket == null) {
			int fileDesc;
			try {
				String env = System.getenv(ANDROID_SOCKET_ENV);
				fileDesc = Integer.parseInt(env);
			} catch (RuntimeException ex) {
				......
			}

			try {
				sServerSocket = new LocalServerSocket(
					createFileDescriptor(fileDesc));
			} catch (IOException ex) {
				.......
			}
		}
	}
		
	......
}
         這個socket介面是通過檔案描述符來建立的,這個檔案描符代表的就是我們前面說的/dev/socket/zygote檔案了。這個檔案描述符是通過環境變數ANDROID_SOCKET_ENV得到的,它定義為:
public class ZygoteInit {
	......

	private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote";
		
	......
}
        那麼,這個環境變數的值又是由誰來設定的呢?我們知道,系統啟動指令碼檔案system/core/rootdir/init.rc是由init程序來解釋執行的,而init程序的原始碼位於system/core/init目錄中,在init.c檔案中,是由service_start函式來解釋init.rc檔案中的service命令的:
void service_start(struct service *svc, const char *dynamic_args)
{
	......

	pid_t pid;

	......

	pid = fork();

	if (pid == 0) {
		struct socketinfo *si;

		......

		for (si = svc->sockets; si; si = si->next) {
			int socket_type = (
				!strcmp(si->type, "stream") ? SOCK_STREAM :
				(!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET));
			int s = create_socket(si->name, socket_type,
				si->perm, si->uid, si->gid);
			if (s >= 0) {
				publish_socket(si->name, s);
			}
		}

		......
	}

	......
}
        每一個service命令都會促使init程序呼叫fork函式來建立一個新的程序,在新的程序裡面,會分析裡面的socket選項,對於每一個socket選項,都會通過create_socket函式來在/dev/socket目錄下建立一個檔案,在這個場景中,這個檔案便是zygote了,然後得到的檔案描述符通過publish_socket函式寫入到環境變數中去:
static void publish_socket(const char *name, int fd)
{
    char key[64] = ANDROID_SOCKET_ENV_PREFIX;
    char val[64];

    strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,
            name,
            sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
    snprintf(val, sizeof(val), "%d", fd);
    add_environment(key, val);

    /* make sure we don't close-on-exec */
    fcntl(fd, F_SETFD, 0);
}
       這裡傳進來的引數name值為"zygote",而ANDROID_SOCKET_ENV_PREFIX在system/core/include/cutils/sockets.h定義為:
#define ANDROID_SOCKET_ENV_PREFIX	"ANDROID_SOCKET_"
        因此,這裡就把上面得到的檔案描述符寫入到以"ANDROID_SOCKET_zygote"為key值的環境變數中。又因為上面的ZygoteInit.registerZygoteSocket函式與這裡建立socket檔案的create_socket函式是執行在同一個程序中,因此,上面的ZygoteInit.registerZygoteSocket函式可以直接使用這個檔案描述符來建立一個Java層的LocalServerSocket物件。如果其它程序也需要開啟這個/dev/socket/zygote檔案來和Zygote程序進行通訊,那就必須要通過檔名來連線這個LocalServerSocket了,參考Android應用程式程序啟動過程的原始碼分析一文中的Step 4,ActivityManagerService是通過Process.start函式來建立一個新的程序的,而Process.start函式會首先通過Socket連線到Zygote程序中,最終由Zygote程序來完成建立新的應用程式程序,而Process類是通過openZygoteSocketIfNeeded函式來連線到Zygote程序中的Socket的:
public class Process {  
	......  
 
	private static void openZygoteSocketIfNeeded()  
			throws ZygoteStartFailedEx {  

		......

		for (int retry = 0  
			; (sZygoteSocket == null) && (retry < (retryCount + 1))  
			; retry++ ) {  

				......

				try {  
					sZygoteSocket = new LocalSocket();  
					sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,  
						LocalSocketAddress.Namespace.RESERVED));  

					sZygoteInputStream  
						= new DataInputStream(sZygoteSocket.getInputStream());  

					sZygoteWriter =  
						new BufferedWriter(  
						new OutputStreamWriter(  
						sZygoteSocket.getOutputStream()),  
						256);  

					......  
				} catch (IOException ex) {  
					......  
				}  
		}  

		......  
	}  

	......  
}
        這裡的ZYGOTE_SOCKET定義為:
public class Process {  
	......  
 
	private static final String ZYGOTE_SOCKET = "zygote";  

	......  
} 
        它剛好就是對應/dev/socket目錄下的zygote檔案了。

        Android系統中的socket機制和binder機制一樣,都是可以用來進行程序間通訊,讀者可以自己對比一下這兩者的不同之處,Binder程序間通訊機制可以參考Android程序間通訊(IPC)機制Binder簡要介紹和學習計劃一文。

       Socket物件建立完成之後,回到Step 3中的ZygoteInit.main函式中,startSystemServer函式來啟動SystemServer元件。

       Step 5. ZygoteInit.startSystemServer
       這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:

public class ZygoteInit {
	......

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

			......

			/* Request to fork the system server process */
			pid = Zygote.forkSystemServer(
				parsedArgs.uid, parsedArgs.gid,
				parsedArgs.gids, debugFlags, null,
				parsedArgs.permittedCapabilities,
				parsedArgs.effectiveCapabilities);
		} catch (IllegalArgumentException ex) {
			......
		}

		/* For child process */
		if (pid == 0) {
			handleSystemServerProcess(parsedArgs);
		}

		return true;
	}
	
	......
}
        這裡我們可以看到,Zygote程序通過Zygote.forkSystemServer函式來建立一個新的程序來啟動SystemServer元件,返回值pid等0的地方就是新的程序要執行的路徑,即新建立的程序會執行handleSystemServerProcess函式。

        Step 6. ZygoteInit.handleSystemServerProcess
        這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:

public class ZygoteInit {
	......

	private static void handleSystemServerProcess(
			ZygoteConnection.Arguments parsedArgs)
			throws ZygoteInit.MethodAndArgsCaller {
		closeServerSocket();

		/*
		* Pass the remaining arguments to SystemServer.
		* "--nice-name=system_server com.android.server.SystemServer"
		*/
		RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
		/* should never reach here */
	}

	......
} 
        由於由Zygote程序建立的子程序會繼承Zygote程序在前面Step 4中建立的Socket檔案描述符,而這裡的子程序又不會用到它,因此,這裡就呼叫closeServerSocket函式來關閉它。這個函式接著呼叫RuntimeInit.zygoteInit函式來進一步執行啟動SystemServer元件的操作。

        Step 7. RuntimeInit.zygoteInit

        這個函式定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java檔案中:

public class RuntimeInit {  
	......  

	public static final void zygoteInit(String[] argv)  
			throws ZygoteInit.MethodAndArgsCaller {  
		......  
  
		zygoteInitNative();  

		......  


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

		String startClass = argv[curArg++];  
		String[] startArgs = new String[argv.length - curArg];  

		System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);  
		invokeStaticMain(startClass, startArgs);  
	}  

	......  
}
         這個函式會執行兩個操作,一個是呼叫zygoteInitNative函式來執行一個Binder程序間通訊機制的初始化工作,這個工作完成之後,這個程序中的Binder物件就可以方便地進行程序間通訊了,另一個是呼叫上面Step 5傳進來的com.android.server.SystemServer類的main函式。

         Step 8. RuntimeInit.zygoteInitNative

         這個函式定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java檔案中:

public class RuntimeInit {  
	......  

	public static final native void zygoteInitNative();  

	......  
}
        這裡可以看出,函式zygoteInitNative是一個Native函式,實現在frameworks/base/core/jni/AndroidRuntime.cpp檔案中,這裡我們就不再細看了,具體可以參考Android應用程式程序啟動過程的原始碼分析一文的Step 9,完成這一步後,這個程序的Binder程序間通訊機制基礎設施就準備好了。

        回到Step 7中的RuntimeInit.zygoteInitNative函式,下一步它就要執行com.android.server.SystemServer類的main函數了。

        Step 9. SystemServer.main

        這個函式定義在frameworks/base/services/java/com/android/server/SystemServer.java檔案中:

public class SystemServer  
{  
	......  

	native public static void init1(String[] args);  

	......  

	public static void main(String[] args) {  
		......  

		init1(args);  

		......  
	} 

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

	......  
}
        這裡的main函式首先會執行JNI方法init1,然後init1會呼叫這裡的init2函式,在init2函式裡面,會建立一個ServerThread執行緒物件來執行一些系統關鍵服務的啟動操作,例如我們在前面兩篇文章Android應用程式安裝過程原始碼分析Android系統預設Home應用程式(Launcher)的啟動過程原始碼分析中提到的PackageManagerService和ActivityManagerService。
        這一步的具體執行過程可以參考Android應用程式安裝過程原始碼分析一文,這裡就不再詳述了。

        這裡執行完成後,層層返回,最後回到上面的Step 3中的ZygoteInit.main函式中,接下來它就要呼叫runSelectLoopMode函式進入一個無限迴圈在前面Step 4中建立的socket介面上等待ActivityManagerService請求建立新的應用程式程序了。

        Step 10. ZygoteInit.runSelectLoopMode

        這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:

public class ZygoteInit {
	......

	private static void runSelectLoopMode() throws MethodAndArgsCaller {
		ArrayList<FileDescriptor> fds = new ArrayList();
		ArrayList<ZygoteConnection> peers = new ArrayList();
		FileDescriptor[] fdArray = new FileDescriptor[4];

		fds.add(sServerSocket.getFileDescriptor());
		peers.add(null);

		int loopCount = GC_LOOP_COUNT;
		while (true) {
			int index;

			......


			try {
				fdArray = fds.toArray(fdArray);
				index = selectReadable(fdArray);
			} catch (IOException ex) {
				throw new RuntimeException("Error in select()", ex);
			}

			if (index < 0) {
				throw new RuntimeException("Error in select()");
			} else if (index == 0) {
				ZygoteConnection newPeer = acceptCommandPeer();
				peers.add(newPeer);
				fds.add(newPeer.getFileDesciptor());
			} else {
				boolean done;
				done = peers.get(index).runOnce();

				if (done) {
					peers.remove(index);
					fds.remove(index);
				}
			}
		}
	}

	......
}      
        這個函式我們已經在Android應用程式程序啟動過程的原始碼分析一文的Step 5中分析過了,這就是在等待ActivityManagerService來連線這個Socket,然後呼叫ZygoteConnection.runOnce函式來建立新的應用程式,有興趣的讀者可以參考Android應用程式程序啟動過程的原始碼分析這篇文章,這裡就不再詳述了。

        這樣,Zygote程序就啟動完成了,學習到這裡,我們終於都對Android系統中的程序有了一個深刻的認識了,這裡總結一下:

        1. 系統啟動時init程序會建立Zygote程序,Zygote程序負責後續Android應用程式框架層的其它程序的建立和啟動工作。

        2. Zygote程序會首先建立一個SystemServer程序,SystemServer程序負責啟動系統的關鍵服務,如包管理服務PackageManagerService和應用程式元件管理服務ActivityManagerService。

        3. 當我們需要啟動一個Android應用程式時,ActivityManagerService會通過Socket程序間通訊機制,通知Zygote程序為這個應用程式建立一個新的程序。

相關推薦

Android系統程序Zygote啟動過程原始碼分析

        在Android系統中,所有的應用程式程序以及系統服務程序SystemServer都是由Zygote程序孕育(fork)出來的,這也許就是為什麼要把它稱為Zygote(受精卵)的原因吧。由於Zygote程序在Android系統中有著如此重要的地位,本文將詳細分

Android系統程序間通訊 IPC 機制Binder中的Server啟動過程原始碼分析

                        在前面一篇文章中,介紹了在Android系統中Binder程序間通訊機制中的Server角色是如何獲得Service Manager遠端介面的,即defaultServiceManager函式的實現。Server獲得了Service Manager遠端介面之後,

Android 8.0系統原始碼分析--openCamera(HAL)啟動過程原始碼分析

     前面我們詳細分析了從應用層呼叫CameraManager的openCamera的方法來開啟相機的邏輯,上次的分析我們來到了CameraServer程序當中,但是還沒有真正看到open操作裝置節點來實現真正開啟的邏輯,遺留的問題也就是從frameworks\av\se

Android 8.0系統原始碼分析--startService啟動過程原始碼分析

   作過android應用開發的同事都非常清楚,android提供了四個元件Activity、Service、BroastcastReceiver、ContentProvider,分別都有不同的作用,這也給我們的應用開發提供了非常大的幫助,因為這四大元件本身就已經處理了很

Android 8.0系統原始碼分析--openCamera啟動過程原始碼分析

     說起Android相機的東西,從應用層的角度來看,基本就是四個重要的節點了:openCamera、createCaptureSession、preview、capture,最複雜的就是preview了,要理解preview,那麼就要求大家對And

Android應用程式啟動過程原始碼分析(2)

Step 9. ActivityStack.startActivityUncheckedLocked         這個函式定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java檔案中: view plain pu

Android應用程式啟動過程原始碼分析

        前文簡要介紹了Android應用程式的Activity的啟動過程。在Android系統中,應用程式是由Activity組成的,因此,應用程式的啟動過程實際上就是應用程式中的預設Activity的啟動過程,本文將詳細分析應用程式框架層的原始碼,瞭解Android

Activity啟動過程原始碼分析Android 8.0)

Activity啟動過程原始碼分析 本文來Activity的啟動流程,一般我們都是通過startActivity或startActivityForResult來啟動目標activity,那麼我們就由此出發探究系統是如何實現目標activity的啟動的。 startActivity(new Intent(con

Netty NioEventLoop 啟動過程原始碼分析

原文連結:https://wangwei.one/posts/netty-nioeventloop-analyse-for-startup.html 前面 ,我們分析了NioEventLoop的建立過程,接下來我們開始分析NioEventLoop的啟動和執行邏輯。

Netty(五)服務端啟動過程原始碼分析——好文摘抄

下面先來一段 Netty 服務端的程式碼: public class NettyServer { public void bind(int port){ // 建立EventLoopGroup EventLoopGroup bossGroup = new

Uboot啟動過程原始碼分析之第二階段

UBoot的最終目標是啟動核心 1.從Flash中讀出核心 2.啟動核心 通過呼叫lib_arm/board.c中的start_armboot函式進入uboot第二階段 第二階段總結圖 typedef struct global_data { bd_t *bd; unsigned

Uboot啟動過程原始碼分析之第一階段(硬體相關)

從上一個部落格知道uboot的入口點在 cpu/arm920t/start.s 開啟cpu/arm920t/start.s 跳轉到reset reset: /* * set the cpu to SVC32 mode// CUP設定為管理模式 */ mrs r0,cps

Android 資料Parcel序列化過程原始碼分析

在Android系統中,所有的服務都必須註冊到ServiceManger中,當客戶程序需要請求某一服務時,首先從服務管家ServiceManger中查找出該服務,然後通過RPC遠端呼叫的方式使用該服務。服務在註冊到ServiceManager時,需要將該服務物件傳送到Ser

U-Boot啟動過程原始碼分析(2)-第二階段

先總述:第一階段cpu/arm920t/start.S和board/smdk2410/lowlevel_init.S進行初始化,再跳到第二階段的入口點lib_arm/board.c中的start_armboot函式。 第二階段start_armboot函式需

Netty入門一:服務端應用搭建 & 啟動過程原始碼分析

最近週末也沒啥事就學學Netty,同時打算寫一些部落格記錄一下(寫的過程理解更加深刻了) 本文主要從三個方法來呈現:Netty核心元件簡介、Netty服務端建立、Netty啟動過程原始碼分析 如果你對Netty有一定的瞭解, 那閱讀起來應該會比較愉快 ## Netty核心元件簡介 ### ByteBu

Android 8.0系統原始碼分析--Activity的視窗Window物件新增過程原始碼分析

     這節我們來看一下Activity的視窗Window物件的建立過程,Activity作為Android提供的四大元件之首,我們之所以能非常簡單的使用它,就是因為它的建立過程中,framework為我們作了大量的初始化工作,包括它的視窗Window、視訊記憶體Surf

Android Framework學習——Launcher啟動應用程式過程原始碼分析

        ActivityInfo aInfo = r.activityInfo;         if (r.packageInfo == null) {             r.packageInfo = getPackageInfo(aInfo.applicationInfo,      

Android 8.0系統原始碼分析--相機createCaptureSession建立過程原始碼分析

     上一次我們詳細分析了openCamera啟動過程的原始碼,從CameraServer程序建立了很多物件,比如CameraDeviceClient、Camera3Device、FrameProcessorBase,而真正開啟相機還是在驅動層中上電後才完成的,有時候真想

linux系統啟動過程簡要分析

com bubuko 加載內核 ice func auth 變量 number 啟動過程 接觸linux系統運維已經好幾年了,常常被問到linux系統啟動流程問題,剛好今天有空來梳理下這個過程:一般來說,所有的操作系統的啟動流程基本就是: 總的來說,linux系統啟動

Android進階3:Activity原始碼分析(2) —— Activity啟動和銷燬流程(8.0)

上篇文章講述了app從啟動建立Activity呼叫onCreate,onStart, onResume方法,這篇文章講述一下Activity啟動的另一個切入點:startActivity方法,啟動Activity。 通過上一篇文章,我們總結一下: 1:A