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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Zygote工作流程分析

發布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Zygote工作流程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Zygote

?????? 接收客戶端創建進程的請求,使用JNI調用linux fork函數創建進程。

Zygote是在Init進程中作為Service被啟動的。Zygote進程的主體是:ZygoteInit。

?????? Zygote進程的啟動可以參考前篇:Android系統啟動過程

   ?http://www.cnblogs.com/bastard/archive/2012/08/28/2660389.html

系統啟動過程如下圖:

  

?

下面主要看看Zygote是如何進行工作的。

一 Zygote工作流程

主函數:

public static void main(String argv[]) {……// Registers a server socket for zygote command connectionsregisterZygoteSocket();/*** Runs the zygote process's select loop. Accepts new connections as* they happen, and reads commands from connections one spawn-request's* worth at a time.*/runSelectLoopMode(); //loop中 }

?

?

消息循環是runSelectLoopMode

private static void runSelectLoopMode() throws MethodAndArgsCaller {
    … …
while (true) {int index;//異步方式 獲取ZygoteConnection Command fdArray = fds.toArray(fdArray);index = selectReadable(fdArray);
if(index == 0) {//讀取新的ZygoteConnection SocketZygoteConnection newPeer = acceptCommandPeer();peers.add(newPeer);fds.add(newPeer.getFileDesciptor());} else {//處理ZygoteConnection Commandboolean done;done = peers.get(index).runOnce();} } }

過程如下圖所示:

??????

    

?

??????

1 ZygoteConnection Command 接收

在ZygoteInit的 main函數中

public static void main(String argv[]) {……// Registers a server socket for zygote command connectionsregisterZygoteSocket();/*** Runs the zygote process's select loop. Accepts new connections as* they happen, and reads commands from connections one spawn-request's* worth at a time.*/runSelectLoopMode(); //loop中 }//registerZygoteSocket注冊了Server 端Socket監聽ZygoteConnection:
private static void registerZygoteSocket() {//” ANDROID_SOCKET_zygote”String env = System.getenv(ANDROID_SOCKET_ENV);fileDesc = Integer.parseInt(env);//private static LocalServerSocket sServerSocket;if (sServerSocket == null) {sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc));} }

  使用到了LocalServerSocket進行通信,具體如何進行請看源碼。

?

2 ZygoteConnection Command處理

  在循環中done = peers.get(index).runOnce();——> ZygoteConnection runOnce

???????

boolean runOnce( ) {Arguments parsedArgs = null;FileDescriptor[] descriptors;//Reads one start command from the command socket.args = readArgumentList();descriptors = mSocket.getAncillaryFileDescriptors();//創建/Forks a new VM instance /process.//使用Jni 調用nativeForkpid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids, parsedArgs.debugFlags, rlimits);//返回兩次if (pid == 0) {// in child serverPipeFd = null;handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);// should never get here, the child is expected to eitherreturn true;} else {// in parent...pid of < 0 means failurechildPipeFd = null;return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);} }

?

3 Zygote創建新進程的執行

從上面的代碼中可以看到創建進程之后返回:

?????? 子進程:handleChildProc

?????? 父進程:handleParentProc

我們關心的是子進程的執行,繼續到handleChildProc中。

// Handles post-fork setup of child proc private void handleChildProc(Arguments parsedArgs,...){……if (parsedArgs.runtimeInit) {if (parsedArgs.invokeWith != null) {         //通過系統調用執行進程WrapperInit.execApplication(parsedArgs.invokeWith,parsedArgs.niceName, parsedArgs.targetSdkVersion,pipeFd, parsedArgs.remainingArgs);} else {//通過尋找到相應目標類的main()函數并執行RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs);}}…… }

?

看到子進程的執行有兩種方式:

  WrapperInit.execApplication和RuntimeInit.zygoteInit

1)通過系統調用的方式執行進程?WrapperInit.execApplication

public static void execApplication(……) {……Zygote.execShell(command.toString()); }public static void execShell(String command) {// using the exec() system callnativeExecShell(command); }

?

?

2)通過尋找到相應目標類的main()函數并執行?RuntimeInit.zygoteInit:

// The main function called when started through the zygote process. public static final void zygoteInit( ){zygoteInitNative();applicationInit(targetSdkVersion, argv); }private static void applicationInit( ) {// Remaining arguments are passed to the start class's static maininvokeStaticMain(args.startClass, args.startArgs); }
通過RuntimeInit調用startClass的main函數。

?

  為何兩種方式?可以參考下面文章:

?????? http://blog.csdn.net/21cnbao/article/details/7791254

  以上是Zygote大概簡要的工作流程,要深入了解進程創建過程還不行,以上兩種方式執行新創建的進程有何區別,

還得熟悉Android,Linux 及其Fork的一些知識和原理。

  linux fork可以參考我轉載的文章:

?????? http://www.cnblogs.com/bastard/archive/2012/08/31/2664896.html

  了解了Zygote大概工作流程,如果我們要創建進程該如何告知Zygote呢?

在StartActivity如果是啟動新的應用就會創建該應用的進程,下面我們可以看一下StartActivity時創建進程的過程。

?

二 應用程序進程的創建過程

?????? 啟動一個新的應用程序為例,啟動新的應用程序時候是以startActivity的方式進行,這個過程大致如下圖:

??????

    

?

  在啟動應用程序的時需要創建應用程序的進程,執行到:

  ActivityManagerService的startProcessLocked函數中;看一下這個函數過程:

private final void startProcessLocked(ProcessRecord app,String hostingType, String hostingNameStr) {// Start the process. It will either succeed and return a result containing// the PID of the new process, or else throw a RuntimeException.Process.ProcessStartResult startResult =Process.start("android.app.ActivityThread",app.processName, uid, uid, gids, debugFlags,app.info.targetSdkVersion, zygoteArgs); }

?

?

  到了Process這個類:Tools for managing OS processes.

public static final ProcessStartResult start(…… ) {return startViaZygote(processClass, niceName, uid, gid, gids,debugFlags, targetSdkVersion, zygoteArgs); }//Starts a new process via the zygote mechanism. private static ProcessStartResult startViaZygote(…… ) {synchronized(Process.class) {ArrayList<String> argsForZygote = new ArrayList<String>();//參數設置// --runtime-init, --setuid=, --setgid=,……//--runtime-init這里決定上面所提到創建新的進程的啟動方式argsForZygote.add("--runtime-init"); argsForZygote.add("--setuid=" + uid);argsForZygote.add("--setgid=" + gid);//……argsForZygote.add(processClass);for (String arg : extraArgs) {argsForZygote.add(arg);} return zygoteSendArgsAndGetResult(argsForZygote);}}

?

?

//Sends an argument list to the zygote process, which starts a new child //and returns the child's pid private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args) {//open socket to Zygote process if not already openopenZygoteSocketIfNeeded();//write ArgumentsZygoteWriter.write(Integer.toString(args.size()));sZygoteWriter.newLine();sZygoteWriter.flush();……}

  通過上面這一段代碼,向Zygote發送創建進程的請求,設置相關的參數。

其中有argsForZygote.add("--runtime-init");??? 決定新創建進程的啟動方式為RuntimeInit.zygoteInit方式啟動:

找到目標類main函數執行。

  processClass"android.app.ActivityThread",將是進程創建之后執行的類,執行其中的main函數。

聯系上面的流程:

  創建進程后執行到RuntimeInit.zygoteInit:(直接找到目標類的main函數調用不是系統調用)

// The main function called when started through the zygote process. public static final void zygoteInit( ){applicationInit(targetSdkVersion, argv); }private static void applicationInit( ) {     //后將執行:ActivityThread的main函數,啟動界面。invokeStaticMain(args.startClass, args.startArgs);}

?

ActivityThread就是應用程序的主線程的入口。

?

  以上便是Zygote工作流程和啟動應用程序創建進程大概簡單過程,其中所涉及到知識和框架比較多,還需要去理解linux fork知識和原理,

進程概念,Android進程通信機制Binder,Activity啟動過程等。這里僅簡單的從代碼上做流程分析。

  參考文檔:

http://blog.csdn.net/luoshengyang/article/details/6689748

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的Zygote工作流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

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