一恋博、內(nèi)容預(yù)覽
二、概述
前面進程系列已經(jīng)更新了四篇葵蒂,本文(基于Android O源碼)交播,梳理應(yīng)用進程的創(chuàng)建流程重虑。
進程系列第一篇---進程基礎(chǔ)
進程系列第二篇---Zygote進程的創(chuàng)建流程
Android進程第三篇---SystemServer進程創(chuàng)建流程
Android進程第四篇---SystemServer進程的啟動流程
下面是一個進程創(chuàng)建架構(gòu)圖践付,可以了解一個進程創(chuàng)建的大概流程。
一共涉及了幾個角色缺厉,發(fā)起進程永高、System進程、Zygote進程提针、新進程
發(fā)起進程
一個App進程可以通過startActivity等系統(tǒng)API請求SystemServer進程創(chuàng)建進程命爬,SystemServer進程把這個活交給了Process.start,這個就是創(chuàng)建進程的入口辐脖。System進程
緊接著SystemServer進程通知ZygoteState創(chuàng)建LocalSocket饲宛,此時,SystemServer進程一直扮演的都是客戶端的角色嗜价。Zygote進程
另一方面艇抠,在Android開機的過程中幕庐,Zygote進程就已經(jīng)早早的啟動了,所以LocalServerSocket就已經(jīng)很早創(chuàng)建了家淤,runSelectLoop開啟了一個死循環(huán)一直accept客戶端的連接异剥,當SystemServer進程把LocalSocket創(chuàng)建出來之后,就可以使用LocalSocket send/recv數(shù)據(jù)了絮重,此時就可以通知LocalServerSocket我要創(chuàng)建一個進程冤寿。進程fork完成之后,返回結(jié)果給System進程的AMS青伤。新進程
Zygote進程把進程fork出來之后督怜,需要做進程的初始化操作,比如設(shè)置進程異常的捕獲方式狠角,開始Binder線程池等等亮蛔,最后進入了ActivityThread的main方法,一個有血有肉的進程正式被啟動了擎厢。
三究流、進程的創(chuàng)建流程
3.1、發(fā)送創(chuàng)建請求动遭,從Process類的start方法開始
所有進程創(chuàng)建的請求都交給Process芬探,從Process類的start方法開始。
frameworks/base/core/java/android/os/Process.java
/**
* Start a new process.
*
* <p>If processes are enabled, a new process is created and the
* static main() function of a <var>processClass</var> is executed there.
* The process will continue running after this function returns.
*
* <p>If processes are not enabled, a new thread in the caller's
* process is created and main() of <var>processClass</var> called there.
*
* <p>The niceName parameter, if not an empty string, is a custom name to
* give to the process instead of using processClass. This allows you to
* make easily identifyable processes even if you are using the same base
* <var>processClass</var> to start them.
*
* When invokeWith is not null, the process will be started as a fresh app
* and not a zygote fork. Note that this is only allowed for uid 0 or when
* debugFlags contains DEBUG_ENABLE_DEBUGGER.
*
* @param processClass The class to use as the process's main entry
* point.
* @param niceName A more readable name to use for the process.
* @param uid The user-id under which the process will run.
* @param gid The group-id under which the process will run.
* @param gids Additional group-ids associated with the process.
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
* @param seInfo null-ok SELinux information for the new process.
* @param abi non-null the ABI this app should be started with.
* @param instructionSet null-ok the instruction set to use.
* @param appDataDir null-ok the data directory of the app.
* @param invokeWith null-ok the command to invoke with.
* @param zygoteArgs Additional arguments to supply to the zygote process.
*
* @return An object that describes the result of the attempt to start the process.
* @throws RuntimeException on fatal start failure
*
* {@hide}
*/
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
舉例:當啟動一個Activity的時候厘惦,發(fā)現(xiàn)Activity所在進程沒有被創(chuàng)建偷仿,就會調(diào)用這個API進程進行創(chuàng)建闲孤。Process.start()方法是阻塞操作谆沃,等待直到進程創(chuàng)建完成并返回相應(yīng)的新進程pid培漏,才完成該方法脑慧。
ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
為了更好的理解各個參數(shù)的含義吕朵,我debug一下炊琉,得到的各個參數(shù)值如下圖(我調(diào)試的過程中發(fā)現(xiàn)九火,頭條一啟動就有很多進程跟著起來钻弄,做ROM工程師真是累啊稼稿,雖然只是打開一個應(yīng)用薄榛,背后喚醒的都不止10個進程,每個進程都需要申請系統(tǒng)的資源让歼,相信每一家ROM對進程的存活都有嚴格的把控3怠)
3.2、整理進程創(chuàng)建的請求參數(shù)
在Process.start之后谋右,有幾個鏈條式的調(diào)用硬猫,Process.start->ZygoteProcess.start->ZygoteProcess.startViaZygote,返回ZygoteState,ZygoteState封裝了Socket的輸入和輸出流啸蜜,zygoteInputStream與zygoteWrite馏予,zygoteWrite可以把創(chuàng)建進程的參數(shù)從SystemServer進程傳遞到Zygote進程,zygoteInputStream可以把返回結(jié)果從Zygote進程返回到SystemServer進程盔性。以下幾個調(diào)用就是不斷的封裝并傳遞創(chuàng)建進程的請求參數(shù)霞丧。
/frameworks/base/core/java/android/os/ZygoteProcess.java
195 public final Process.ProcessStartResult start(final String processClass,
196 final String niceName,
197 int uid, int gid, int[] gids,
198 int debugFlags, int mountExternal,
199 int targetSdkVersion,
200 String seInfo,
201 String abi,
202 String instructionSet,
203 String appDataDir,
204 String invokeWith,
205 String[] zygoteArgs) {
206 try {
207 return startViaZygote(processClass, niceName, uid, gid, gids,
208 debugFlags, mountExternal, targetSdkVersion, seInfo,
209 abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
210 } catch (ZygoteStartFailedEx ex) {
211 Log.e(LOG_TAG,
212 "Starting VM process through Zygote failed");
213 throw new RuntimeException(
214 "Starting VM process through Zygote failed", ex);
215 }
216 }
/frameworks/base/core/java/android/os/ZygoteProcess.java
329 private Process.ProcessStartResult startViaZygote(final String processClass,
330 final String niceName,
331 final int uid, final int gid,
332 final int[] gids,
333 int debugFlags, int mountExternal,
334 int targetSdkVersion,
335 String seInfo,
336 String abi,
337 String instructionSet,
338 String appDataDir,
339 String invokeWith,
340 String[] extraArgs)
341 throws ZygoteStartFailedEx {
342 ArrayList<String> argsForZygote = new ArrayList<String>();
......
430 synchronized(mLock) {
431 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
432 }
433 }
該過程主要工作是生成argsForZygote列表,把startViaZygote方法的參數(shù)存放到這個列表里面冕香。并且調(diào)用zygoteSendArgsAndGetResult請求Zygotefork進程蛹尝。
3.3、創(chuàng)建Socket悉尾,給Zygote進程發(fā)送進程創(chuàng)建的請求參數(shù)
/frameworks/base/core/java/android/os/ZygoteProcess.java
454 @GuardedBy("mLock")
455 private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
456 Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
457
458 if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
459 try {
460 primaryZygoteState = ZygoteState.connect(mSocket);
461 } catch (IOException ioe) {
462 throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
463 }
464 }
465
466 if (primaryZygoteState.matches(abi)) {
467 return primaryZygoteState;
468 }
469
470 // The primary zygote didn't match. Try the secondary.
471 if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
472 try {
473 secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
474 } catch (IOException ioe) {
475 throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
476 }
477 }
478 //判斷當前的abi來選擇與zygote還是zygote64來進行通信
479 if (secondaryZygoteState.matches(abi)) {
480 return secondaryZygoteState;
481 }
482
483 throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
484 }
通過前面的文章可知道突那,Zygote進程有兩個Socket,這里當主zygote沒能匹配成功构眯,則嘗試第二個mSecondarySocket來連接愕难。
/frameworks/base/core/java/android/os/ZygoteProcess.java
92 public static ZygoteState connect(String socketAddress) throws IOException {
93 DataInputStream zygoteInputStream = null;
94 BufferedWriter zygoteWriter = null;
95 final LocalSocket zygoteSocket = new LocalSocket();
96
97 try {
98 zygoteSocket.connect(new LocalSocketAddress(socketAddress,
99 LocalSocketAddress.Namespace.RESERVED));
100
101 zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());
102
103 zygoteWriter = new BufferedWriter(new OutputStreamWriter(
104 zygoteSocket.getOutputStream()), 256);
105 } catch (IOException ex) {
106 try {
107 zygoteSocket.close();
108 } catch (IOException ignore) {
109 }
110
111 throw ex;
112 }
113
114 String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
115 Log.i("Zygote", "Process: zygote socket " + socketAddress + " opened, supported ABIS: "
116 + abiListString);
117
118 return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
119 Arrays.asList(abiListString.split(",")));
120 }
這個方法主要是建立了SystemServer(Client)這一邊的Socket---LocalSocket,與Zygote進程的LocalServerSocket成功連接之后惫霸,獲取這個LocalSocket的輸入流zygoteInputStream與輸出流zygoteWriter猫缭,并且將他們封裝到ZygoteState中再返回。關(guān)于Socket的工作原理壹店,移步本系列第三篇博客猜丹。
253 @GuardedBy("mLock")
254 private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
255 ZygoteState zygoteState, ArrayList<String> args)
256 throws ZygoteStartFailedEx {
257 try {
258 // Throw early if any of the arguments are malformed. This means we can
259 // avoid writing a partial response to the zygote.
260 int sz = args.size();
261 for (int i = 0; i < sz; i++) {
262 if (args.get(i).indexOf('\n') >= 0) {
263 throw new ZygoteStartFailedEx("embedded newlines not allowed");
264 }
265 }
266
........
//1、從ZygoteState中取出輸入流和輸出流
277 final BufferedWriter writer = zygoteState.writer;
278 final DataInputStream inputStream = zygoteState.inputStream;
279 //2硅卢、用輸入流將創(chuàng)建進程的參數(shù)傳遞給Zygote進程
280 writer.write(Integer.toString(args.size()));
281 writer.newLine();
282
283 for (int i = 0; i < sz; i++) {
284 String arg = args.get(i);
285 writer.write(arg);
286 writer.newLine();
287 }
288
289 writer.flush();
290
291 //創(chuàng)建Process.ProcessStartResult用于存放fork進程的返回結(jié)果
292 Process.ProcessStartResult result = new Process.ProcessStartResult();
293
294 // Always read the entire result from the input stream to avoid leaving
295 // bytes in the stream for future process starts to accidentally stumble
296 // upon.
//輸入流讀取Zygote進程創(chuàng)建進程之后返回的數(shù)據(jù)射窒,保存在Process.ProcessStartResult中
297 result.pid = inputStream.readInt();
298 result.usingWrapper = inputStream.readBoolean();
299 //通過判斷result.pid 是否創(chuàng)建成功
300 if (result.pid < 0) {
301 throw new ZygoteStartFailedEx("fork() failed");
302 }
303 return result;
304 } catch (IOException ex) {
305 zygoteState.close();
306 throw new ZygoteStartFailedEx(ex);
307 }
308 }
這段做的工作主要是從ZygoteState中取出輸入流和輸出流,然后和Server端的Zygote進程的LocketServerSocket進行通信将塑。將AMS中創(chuàng)建進程的參數(shù)傳遞給Zygote進程脉顿。Zygote進程fork完成之后, inputStream.readInt()就能讀取出返回結(jié)果点寥,如果小于0艾疟,代表創(chuàng)建失敗,不小于0代表創(chuàng)建成功开财。
這段代碼存在一個問題汉柒,如果Zygote進程fork進程超時,System這段遲遲不能get到返回結(jié)果责鳍,會引起什么后果?
試想一下兽间,當 AMS 需要創(chuàng)建進程時, 會通過 Socket 與 zygote 進程通信, 當 zygote 接收到請求后會 fork 出一個子進程, 并將其 pid 返回給 AMS历葛。需要注意的是, 在收到 pid 之前, AMS 會一直持鎖等待,而且這里持有的是AMS大鎖, 所以就會 block 其他重要線程, 導(dǎo)致系統(tǒng)卡死,用戶反饋內(nèi)容也會主要圍繞 "系統(tǒng)卡死" "按鍵沒有反應(yīng)" 等等恤溶。
那如何解決這個問題乓诽?google其實有注意到,準備加一個超時機制咒程,但是一直沒有加上鸠天,但是這種情況也是治標不治本,解決這種問題還是要具體分析帐姻,是內(nèi)存碎片嚴重導(dǎo)致fork進程申請page失敗稠集,還是其他原因,需要根據(jù)Log具體對待饥瓷。
3.4剥纷、Zygote進程接收請求參數(shù)
到這里,Client段的工作就全部看完了呢铆,現(xiàn)在去看看Socket的服務(wù)端晦鞋。再次回顧一下那段“模板”代碼。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
//1棺克、創(chuàng)建ZygoteServer
ZygoteServer zygoteServer = new ZygoteServer();
try {
//2悠垛、創(chuàng)建一個Server端的Socket
zygoteServer.registerServerSocket(socketName);
//3、加載進程的資源和類
preload(bootTimingsTraceLog);
if (startSystemServer) {
//4娜谊、開啟SystemServer進程鼎文,這是受精卵進程的第一次分裂
startSystemServer(abiList, socketName, zygoteServer);
}
//5、啟動一個死循環(huán)監(jiān)聽來自Client端的消息
zygoteServer.runSelectLoop(abiList);
//6因俐、關(guān)閉SystemServer的Socket
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
//7拇惋、這里捕獲這個異常調(diào)用MethodAndArgsCaller的run方法。
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
注釋寫的很詳細了抹剩,不多做解釋撑帖,直接看runSelectLoop方法。
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
136 void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
137 ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
138 ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
139 //將服務(wù)端LocalServerSocket的fd加進fds中
140 fds.add(mServerSocket.getFileDescriptor());
141 peers.add(null);
142
143 while (true) {
144 StructPollfd[] pollFds = new StructPollfd[fds.size()];
145 for (int i = 0; i < pollFds.length; ++i) {
146 pollFds[i] = new StructPollfd();
147 pollFds[i].fd = fds.get(i);
148 pollFds[i].events = (short) POLLIN;
149 }
150 try {
//處理輪詢狀態(tài)澳眷,當pollFds有事件到來則往下執(zhí)行胡嘿,否則阻塞在這里
151 Os.poll(pollFds, -1);
152 } catch (ErrnoException ex) {
153 throw new RuntimeException("poll failed", ex);
154 }
//當接收到客戶端發(fā)出連接請求 或者數(shù)據(jù)處理請求到來,則往下執(zhí)行钳踊;否則進入continue衷敌,跳出本次循環(huán)。
155 for (int i = pollFds.length - 1; i >= 0; --i) {
156 if ((pollFds[i].revents & POLLIN) == 0) {
157 continue;
158 }
//當i為0的時候拓瞪,創(chuàng)建ZygoteConnection缴罗,實質(zhì)就創(chuàng)建LocalServerSocket
159 if (i == 0) {
160 ZygoteConnection newPeer = acceptCommandPeer(abiList);
161 peers.add(newPeer);
//將LocalServerSocket的fd添加到fds
162 fds.add(newPeer.getFileDesciptor());
163 } else {
將LocalServerSocket的fd取出來,執(zhí)行runOnce
164 boolean done = peers.get(i).runOnce(this);
165 if (done) {
//完成之后將fd與ZygoteConnection移除
166 peers.remove(i);
167 fds.remove(i);
168 }
169 }
170 }
171 }
172 }
173}
runSelectLoop中有一個while死循環(huán)祭埂,接收進程創(chuàng)建請求面氓,當來了一個請求,就會走runOnce方法
78 /**
79 * Waits for and accepts a single command connection. Throws
80 * RuntimeException on failure.
81 */
82 private ZygoteConnection acceptCommandPeer(String abiList) {
83 try {
84 return createNewConnection(mServerSocket.accept(), abiList);
85 } catch (IOException ex) {
86 throw new RuntimeException(
87 "IOException during accept()", ex);
88 }
89 }
acceptCommandPeer中調(diào)用createNewConnection,返回值是一個ZygoteConnection舌界,封裝了mServerSocket的輸入流mSocketReader與輸出流mSocketOutStream掘譬,這個與Clinet端的ZygoteState有著異曲同工之妙啊。
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
91 ZygoteConnection(LocalSocket socket, String abiList) throws IOException {
92 mSocket = socket;
93 this.abiList = abiList;
94
95 mSocketOutStream
96 = new DataOutputStream(socket.getOutputStream());
97
98 mSocketReader = new BufferedReader(
99 new InputStreamReader(socket.getInputStream()), 256);
100
101 mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);
102
103 try {
104 peer = mSocket.getPeerCredentials();
105 } catch (IOException ex) {
106 Log.e(TAG, "Cannot read peer credentials", ex);
107 throw ex;
108 }
109 }
3.5呻拌、Zygote進程處理創(chuàng)建進程請求葱轩,fork進程
在ZygoteConnection創(chuàng)建好了之后,就執(zhí)行runOnce真正處理進程的創(chuàng)建請求了藐握。
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
134 boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
135
136 String args[];
137 Arguments parsedArgs = null;
138 FileDescriptor[] descriptors;
139
140 try {
//把進程創(chuàng)建的參數(shù)讀取出來
141 args = readArgumentList();
142 descriptors = mSocket.getAncillaryFileDescriptors();
143 } catch (IOException ex) {
144 Log.w(TAG, "IOException on command socket " + ex.getMessage());
145 closeSocket();
146 return true;
147 }
148
149 if (args == null) {
150 // EOF reached.
//參數(shù)為null靴拱,需要關(guān)閉之前創(chuàng)建的Socket,進程創(chuàng)建請求參數(shù)為null還沒有仔細的調(diào)查過
151 closeSocket();
152 return true;
153 }
........
162
163 int pid = -1;
164 FileDescriptor childPipeFd = null;
165 FileDescriptor serverPipeFd = null;
166
167 try {
//將進程創(chuàng)建請求參數(shù)整理成Arguments對象
168 parsedArgs = new Arguments(args);
........
238 //創(chuàng)建子進程,底層調(diào)用fork函數(shù)趾娃,返回值有兩個缭嫡,基于寫時復(fù)制
239 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
240 parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
241 parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
242 parsedArgs.appDataDir);
243 } catch (ErrnoException ex) {
244 logAndPrintError(newStderr, "Exception creating pipe", ex);
245 } catch (IllegalArgumentException ex) {
246 logAndPrintError(newStderr, "Invalid zygote arguments", ex);
247 } catch (ZygoteSecurityException ex) {
248 logAndPrintError(newStderr,
249 "Zygote security policy prevents request: ", ex);
250 }
251
252 try {
//pid==0代表是新創(chuàng)建的子進程
253 if (pid == 0) {
254 //關(guān)閉從Zygote進程繼承而來的Socket
255 zygoteServer.closeServerSocket();
256 IoUtils.closeQuietly(serverPipeFd);
257 serverPipeFd = null;
//處理子進程接下來的工作
258 handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
259
260 // should never get here, the child is expected to either
261 // throw Zygote.MethodAndArgsCaller or exec().
262 return true;
263 } else {
264 //大于0,是父進程抬闷,也就是Zygote進程
265 IoUtils.closeQuietly(childPipeFd);
266 childPipeFd = null;
//處理父進程接下來的工作
267 return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
268 }
269 } finally {
270 IoUtils.closeQuietly(childPipeFd);
271 IoUtils.closeQuietly(serverPipeFd);
272 }
273 }
在調(diào)用Zygote.forkAndSpecialize之前妇蛀,需要調(diào)用readArgumentList把創(chuàng)建進程的請求參數(shù)從Socket中讀取出來,放在一個名為result的String數(shù)組中笤成。
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
631 /**
632 * Reads an argument list from the command socket/
633 * @return Argument list or null if EOF is reached
634 * @throws IOException passed straight through
635 */
636 private String[] readArgumentList()
637 throws IOException {
......
649 int argc;
650
651 try {
652 String s = mSocketReader.readLine();
653
654 if (s == null) {
655 // EOF reached.
656 return null;
657 }
658 argc = Integer.parseInt(s);
659 } catch (NumberFormatException ex) {
660 Log.e(TAG, "invalid Zygote wire format: non-int at argc");
661 throw new IOException("invalid wire format");
662 }
663
664 // See bug 1092107: large argc can be used for a DOS attack
665 if (argc > MAX_ZYGOTE_ARGC) {
666 throw new IOException("max arg count exceeded");
667 }
668
669 String[] result = new String[argc];
670 for (int i = 0; i < argc; i++) {
671 result[i] = mSocketReader.readLine();
672 if (result[i] == null) {
673 // We got an unexpected EOF.
674 throw new IOException("truncated request");
675 }
676 }
677
678 return result;
679 }
參數(shù)有了就調(diào)用Zygote.forkAndSpecialize方法fork進程了评架,關(guān)于進程的fork,第三篇寫的更詳細炕泳,這里不贅述纵诞。
99 public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
100 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
101 int[] fdsToIgnore, String instructionSet, String appDataDir) {
102 VM_HOOKS.preFork();
103 // Resets nice priority for zygote process.
104 resetNicePriority();
//jni技術(shù)調(diào)用fork函數(shù)
105 int pid = nativeForkAndSpecialize(
106 uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
107 fdsToIgnore, instructionSet, appDataDir);
108 // Enable tracing as soon as possible for the child process.
109 if (pid == 0) {
110 Trace.setTracingEnabled(true);
111
112 // Note that this event ends at the end of handleChildProc,
113 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
114 }
115 VM_HOOKS.postForkCommon();
116 return pid;
117 }
3.6、進程創(chuàng)建成功培遵,新進程做初始化
當forkAndSpecialize完成之后浙芙,進程就被創(chuàng)建出來了,但是這個進程是光禿禿的籽腕,還需一些工作要處理嗡呼,即走進handleChildProc方法。
786 private void handleChildProc(Arguments parsedArgs,
787 FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
788 throws Zygote.MethodAndArgsCaller {
.......
//設(shè)置進程名字
811 if (parsedArgs.niceName != null) {
812 Process.setArgV0(parsedArgs.niceName);
813 }
814
815 // End of the postFork event.
816 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
817 if (parsedArgs.invokeWith != null) {
818 WrapperInit.execApplication(parsedArgs.invokeWith,
819 parsedArgs.niceName, parsedArgs.targetSdkVersion,
820 VMRuntime.getCurrentInstructionSet(),
821 pipeFd, parsedArgs.remainingArgs);
822 } else {
//做進程的一些初始化操作皇耗,與System進程創(chuàng)建一致的
823 ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
824 parsedArgs.remainingArgs, null /* classLoader */);
825 }
826 }
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
829 public static final void zygoteInit(int targetSdkVersion, String[] argv,
830 ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
831 if (RuntimeInit.DEBUG) {
832 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
833 }
834
835 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
//見本系列第三篇文章3.5.1
836 RuntimeInit.redirectLogStreams();
837 //見本系列第三篇文章3.5.2
838 RuntimeInit.commonInit();
//見本系列第三篇文章3.5.3
839 ZygoteInit.nativeZygoteInit();
//見本系列第三篇文章3.5.4
840 RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
841 }
842
zygoteInit與System進程創(chuàng)建是一致的南窗,每個進程在創(chuàng)建出來之后,都需要做四件事情郎楼。
- 重定向log輸出
- 通用的一些初始化万伤,比如設(shè)置進程的異常捕獲方式、時區(qū)等
- 調(diào)用nativeZygoteInit進行Zygote的初始化呜袁,開啟Binder線程池
- 調(diào)用applicationInit進行應(yīng)用的初始化
在此不贅述敌买,可移步見本系列第三篇文章。這里看一下applicationInit進行應(yīng)用的初始化傅寡。
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
289 protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
290 throws Zygote.MethodAndArgsCaller {
.....
303 final Arguments args;
304 try {
305 args = new Arguments(argv);
306 } catch (IllegalArgumentException ex) {
307 Slog.e(TAG, ex.getMessage());
308 // let the process exit
309 return;
310 }
.....
315 // 喚醒進程的main方法
316 invokeStaticMain(args.startClass, args.startArgs, classLoader);
317 }
此處的args.startClass為android.app.ActivityThread.java放妈,當fork System進程的時候北救,args.startClass為com.android.server.SystemServer.java荐操。
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
231 private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
232 throws Zygote.MethodAndArgsCaller {
233 Class<?> cl;
234
235 try {
236 cl = Class.forName(className, true, classLoader);
237 } catch (ClassNotFoundException ex) {
238 throw new RuntimeException(
239 "Missing class when invoking static main " + className,
240 ex);
241 }
242
243 Method m;
244 try {
//"main是寫死的芜抒,Android所有應(yīng)用進程的入口就是android.app.ActivityThread.java中的main方法
245 m = cl.getMethod("main", new Class[] { String[].class });
246 } catch (NoSuchMethodException ex) {
247 throw new RuntimeException(
248 "Missing static main on " + className, ex);
249 } catch (SecurityException ex) {
250 throw new RuntimeException(
251 "Problem getting static main on " + className, ex);
252 }
.......
266 throw new Zygote.MethodAndArgsCaller(m, argv);
267 }
invokeStaticMain主要反射了android.app.ActivityThread.java中的main方法,得到Method對象m托启,為了清除棧幀宅倒,為新創(chuàng)建的進行一個干凈的環(huán)境,最后拋出一個異常Zygote.MethodAndArgsCaller屯耸。這個異常會在ZygoteInit的main中被捕獲拐迁。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
.....
//1、啟動一個死循環(huán)監(jiān)聽來自Client端的消息
zygoteServer.runSelectLoop(abiList);
//2疗绣、關(guān)閉SystemServer的Socket
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
//3线召、這里捕獲這個異常調(diào)用MethodAndArgsCaller的run方法。
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
捕獲之后多矮,調(diào)用MethodAndArgsCaller的run方法缓淹,終于進入了ActivityThread的main方法了,一個有血有肉的進程就啟動成功了塔逃。
225 public static class MethodAndArgsCaller extends Exception
226 implements Runnable {
227 /** method to call */
228 private final Method mMethod;
229
230 /** argument array */
231 private final String[] mArgs;
232
233 public MethodAndArgsCaller(Method method, String[] args) {
234 mMethod = method;
235 mArgs = args;
236 }
237
238 public void run() {
239 try {
240 mMethod.invoke(null, new Object[] { mArgs });
241 } catch (IllegalAccessException ex) {
242 throw new RuntimeException(ex);
243 } catch (InvocationTargetException ex) {
244 Throwable cause = ex.getCause();
245 if (cause instanceof RuntimeException) {
246 throw (RuntimeException) cause;
247 } else if (cause instanceof Error) {
248 throw (Error) cause;
249 }
250 throw new RuntimeException(ex);
251 }
252 }
253 }
254}
進程被創(chuàng)建出來了讯壶,系統(tǒng)中資源和類我們就可以直接使用了,這是怎么回事湾盗?由于Android系統(tǒng)基本所有進程的創(chuàng)建都是交給Zygote進程創(chuàng)建的伏蚊,而進程的fork基于寫時復(fù)制技術(shù),所以Zygote進程啟動時候加載的資源也會被應(yīng)用進程所使用格粪,如下圖躏吊,原來進程中所需要的資源,庫等都是由它老子辦好了帐萎,繼承過來就行比伏。資源的加載過程參考本系列第二篇博客。
四吓肋、總結(jié)
應(yīng)用進程的創(chuàng)建和System進程的創(chuàng)建基本上一致凳怨,尤其是在fork進程之后的邏輯,是一模一樣的是鬼,不同的是肤舞,System進程是Zygote進程的大兒子,由自己親手創(chuàng)建均蜜,而其他應(yīng)用進程是通過Process.start發(fā)送創(chuàng)建請求李剖,Zygote幫忙創(chuàng)建的。這個過程其實不算復(fù)雜囤耳,創(chuàng)建流程的詳細序列圖如下篙顺。
進程的創(chuàng)建花了四篇的篇幅,從Zygote進程的創(chuàng)建德玫,System進程的創(chuàng)建和啟動匪蟀,在到應(yīng)用進程的創(chuàng)建,到此就結(jié)束了宰僧,下面將會梳理AMS中進程的數(shù)據(jù)結(jié)構(gòu)---ProcessRecord材彪。