【Android開(kāi)發(fā)高級(jí)系列】Android多進(jìn)程專(zhuān)題

1 進(jìn)程啟動(dòng)過(guò)程

???????? Android應(yīng)用程序框架層創(chuàng)建的應(yīng)用程序進(jìn)程具有兩個(gè)特點(diǎn),一是進(jìn)程的入口函數(shù)是ActivityThread.main贰镣,二是進(jìn)程天然支持Binder進(jìn)程間通信機(jī)制晤柄;這兩個(gè)特點(diǎn)都是在進(jìn)程的初始化過(guò)程中實(shí)現(xiàn)的页徐,本文將詳細(xì)分析Android應(yīng)用程序進(jìn)程創(chuàng)建過(guò)程中是如何實(shí)現(xiàn)這兩個(gè)特點(diǎn)的笼才。

? ? ? ? Android應(yīng)用程序框架層創(chuàng)建的應(yīng)用程序進(jìn)程的入口函數(shù)是ActivityThread.main比較好理解溢谤,即進(jìn)程創(chuàng)建完成之后斩松,Android應(yīng)用程序框架層就會(huì)在這個(gè)進(jìn)程中將ActivityThread類(lèi)加載進(jìn)來(lái)伶唯,然后執(zhí)行它的main函數(shù),這個(gè)main函數(shù)就是進(jìn)程執(zhí)行消息循環(huán)的地方了惧盹。Android應(yīng)用程序框架層創(chuàng)建的應(yīng)用程序進(jìn)程天然支持Binder進(jìn)程間通信機(jī)制這個(gè)特點(diǎn)應(yīng)該怎么樣理解呢乳幸?前面我們?cè)趯W(xué)習(xí)Android系統(tǒng)的Binder進(jìn)程間通信機(jī)制時(shí)說(shuō)到,它具有四個(gè)組件钧椰,分別是驅(qū)動(dòng)程序粹断、守護(hù)進(jìn)程、Client以及Server嫡霞,其中Server組件在初始化時(shí)必須進(jìn)入一個(gè)循環(huán)中不斷地與Binder驅(qū)動(dòng)程序進(jìn)行到交互瓶埋,以便獲得Client組件發(fā)送的請(qǐng)求,具體可參考Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過(guò)程源代碼分析一文诊沪,但是养筒,當(dāng)我們?cè)贏ndroid應(yīng)用程序中實(shí)現(xiàn)Server組件的時(shí)候,我們并沒(méi)有讓進(jìn)程進(jìn)入一個(gè)循環(huán)中去等待Client組件的請(qǐng)求端姚,然而晕粪,當(dāng)Client組件得到這個(gè)Server組件的遠(yuǎn)程接口時(shí),卻可以順利地和Server組件進(jìn)行進(jìn)程間通信渐裸,這就是因?yàn)锳ndroid應(yīng)用程序進(jìn)程在創(chuàng)建的時(shí)候就已經(jīng)啟動(dòng)了一個(gè)線程池來(lái)支持Server組件和Binder驅(qū)動(dòng)程序之間的交互了巫湘,這樣装悲,極大地方便了在Android應(yīng)用程序中創(chuàng)建Server組件。

? ? ? ? 在Android應(yīng)用程序框架層中尚氛,是由ActivityManagerService組件負(fù)責(zé)為Android應(yīng)用程序創(chuàng)建新的進(jìn)程的诀诊,它本來(lái)也是運(yùn)行在一個(gè)獨(dú)立的進(jìn)程之中,不過(guò)這個(gè)進(jìn)程是在系統(tǒng)啟動(dòng)的過(guò)程中創(chuàng)建的阅嘶。ActivityManagerService組件一般會(huì)在什么情況下會(huì)為應(yīng)用程序創(chuàng)建一個(gè)新的進(jìn)程呢畏梆?當(dāng)系統(tǒng)決定要在一個(gè)新的進(jìn)程中啟動(dòng)一個(gè)Activity或者Service時(shí),它就會(huì)創(chuàng)建一個(gè)新的進(jìn)程了奈懒,然后在這個(gè)新的進(jìn)程中啟動(dòng)這個(gè)Activity或者Service,具體可以參考Android系統(tǒng)在新進(jìn)程中啟動(dòng)自定義服務(wù)過(guò)程(startService)的原理分析宪巨、Android應(yīng)用程序啟動(dòng)過(guò)程源代碼分析Android應(yīng)用程序在新的進(jìn)程中啟動(dòng)新的Activity的方法和過(guò)程分析這三篇文章磷杏。

?? ? ? ?ActivityManagerService啟動(dòng)新的進(jìn)程是從其成員函數(shù)startProcessLocked開(kāi)始的,在深入分析這個(gè)過(guò)程之前捏卓,我們先來(lái)看一下進(jìn)程創(chuàng)建過(guò)程的序列圖极祸,然后再詳細(xì)分析每一個(gè)步驟。

Step 1.ActivityManagerService.startProcessLocked

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/services/Java/com/android/server/am/ActivityManagerService.java文件中:

public?final?class?ActivityManagerService?extends?ActivityManagerNative?implements?Watchdog.Monitor,?BatteryStatsImpl.BatteryCallback?{

????......

????private?final?void?startProcessLocked(ProcessRecord?app, String?hostingType, String?hostingNameStr){

????????......

????????try{

????????????int?uid?=?app.info.uid;

????????????int[]?gids?=?null;

????????????try{

????????????????gids?=?mContext.getPackageManager().getPackageGids(app.info.packageName);

????????????}?catch(PackageManager.NameNotFoundException?e)?{

????????????????......

????????????}

????????????......

????????????int?debugFlags?=?0;

????????????......

????????????int?pid?=?Process.start("android.app.ActivityThread", mSimpleProcessManagement ? app.processName?:?null,?uid,?uid, gids,?debugFlags,?null);

????????????......

????????}?catch(RuntimeException?e)?{

????????????......

????????}

????}

????......

}?

?? ? ? ?它調(diào)用了Process.start函數(shù)開(kāi)始為應(yīng)用程序創(chuàng)建新的進(jìn)程怠晴,注意遥金,它傳入一個(gè)第一個(gè)參數(shù)為"android.app.ActivityThread",這就是進(jìn)程初始化時(shí)要加載的Java類(lèi)了蒜田,把這個(gè)類(lèi)加載到進(jìn)程之后稿械,就會(huì)把它里面的靜態(tài)成員函數(shù)main作為進(jìn)程的入口點(diǎn),后面我們會(huì)看到冲粤。


Step 2. Process.start

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中:

public?class?Process?{

????......

????public?static?final?int?start(final?String?processClass,?final?String?niceName,?int?uid,?int?gid,?int[]?gids,?int?debugFlags, String[]?zygoteArgs)

????{

????????if(supportsProcesses())?{

? ? ? ?????try{

???????????????return?startViaZygote(processClass,?niceName,?uid,?gid,?gids, debugFlags,?zygoteArgs);

? ? ? ? ????}?catch(ZygoteStartFailedEx?ex)?{

????????????????......

????????????}

? ? ????}?else{

????????????......

????????????return?0;

????????}

????}

????......

}

?? ? ? 這里的supportsProcesses函數(shù)返回值為true美莫,它是一個(gè)Native函數(shù),實(shí)現(xiàn)在frameworks/base/core/jni/android_util_Process.cpp文件中:

jboolean?android_os_Process_supportsProcesses(JNIEnv*?env,?jobject?clazz)

{

????return?ProcessState::self()->supportsProcesses();

}

?? ? ? ProcessState::supportsProcesses函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:

bool?ProcessState::supportsProcesses()?const

{

????return?mDriverFD?>=?0;

}

?? ? ? 這里的mDriverFD是設(shè)備文件/dev/binder的打開(kāi)描述符梯捕,如果成功打開(kāi)了這個(gè)設(shè)備文件厢呵,那么它的值就會(huì)大于等于0,因此傀顾,它的返回值為true襟铭。

?? ? ? 回到Process.start函數(shù)中,它調(diào)用startViaZygote函數(shù)進(jìn)一步操作短曾。


Step3.?Process.startViaZygote

?? ? ??這個(gè)函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中:

public?class?Process?{

????......

????private?static?int?startViaZygote(final?String?processClass,?final?String?niceName,?final?int?uid,?

? ??final?int?gid,?final?int[]?gids,?int?debugFlags, String[]?extraArgs)?throwsZygoteStartFailedEx?

????{

? ??????int?pid;

????????synchronized(Process.class)?{????

? ????? ? ? ArrayList?argsForZygote?=?new?ArrayList();

????? ? ? ? //?--runtime-init,?--setuid=,?--setgid=,

????? ? ? ? //?and?--setgroups=?must?go?first

????? ? ? ? argsForZygote.add("--runtime-init");

????? ? ? ? argsForZygote.add("--setuid="+?uid);

? ????? ? ? argsForZygote.add("--setgid="+?gid);

? ????? ? ??if?((debugFlags?&?Zygote.DEBUG_ENABLE_SAFEMODE)?!=?0)?{

? ????? ? ? ? ? argsForZygote.add("--enable-safemode");

????? ? ? ? }

????????????if?((debugFlags?&?Zygote.DEBUG_ENABLE_DEBUGGER)?!=?0)?{

????? ? ? ? ? ? argsForZygote.add("--enable-debugger");????

????????????}

????????????if?((debugFlags?&?Zygote.DEBUG_ENABLE_CHECKJNI)?!=?0)?{

? ? ? ????? ? ? argsForZygote.add("--enable-checkjni");

????????????}

????????????if?((debugFlags?&?Zygote.DEBUG_ENABLE_ASSERT)?!=?0)?{

? ????? ? ? ? ? argsForZygote.add("--enable-assert");

????????????}

? ????? ? ? //TODO?optionally?enable?debuger

? ????? ? ? //argsForZygote.add("--enable-debugger");

? ????? ? ? //?--setgroups?is?a?comma-separated?list

? ? ????? ??if?(gids?!=?null?&&?gids.length?>?0)?{

? ? ? ????? ? ? StringBuilder?sb?=?new?StringBuilder();

? ? ? ????? ? ? sb.append("--setgroups=");

????? ? ? ? ? ??int?sz?=?gids.length;

????????????????for?(int?i?=?0;?i?<?sz;?i++)?{

? ? ? ? ? ????? ? ??if?(i?!=?0)?{

? ? ? ? ? ????? ? ? ? ? sb.append(',');

????????????????????}

????????????????????sb.append(gids[i]);

????????????????}

????????????????argsForZygote.add(sb.toString());

????????????}

????????????if?(niceName?!=?null)?{

? ? ? ? ? ? ????argsForZygote.add("--nice-name="+?niceName);

????????????}

????????????argsForZygote.add(processClass);

????????????if?(extraArgs?!=?null)?{

? ? ? ? ? ??????for(String?arg?:?extraArgs)?{

????????????????????argsForZygote.add(arg);

????????????????}

????????????}

? ? ? ? ????pid?=?zygoteSendArgsAndGetPid(argsForZygote);

????????}

????}

......

}??

?? ? ? ?這個(gè)函數(shù)將創(chuàng)建進(jìn)程的參數(shù)放到argsForZygote列表中去寒砖,如參數(shù)"--runtime-init"表示要為新創(chuàng)建的進(jìn)程初始化運(yùn)行時(shí)庫(kù),然后調(diào)用zygoteSendAndGetPid函數(shù)進(jìn)一步操作嫉拐。


Step 4. Process.zygoteSendAndGetPid

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中:

public?class?Process?{

????......

????private?static?int?zygoteSendArgsAndGetPid(ArrayList?args)?throws?ZygoteStartFailedEx?

????{

????????int?pid;

????????openZygoteSocketIfNeeded();

????????try{

????????????/**

????????????*?See?com.android.internal.os.ZygoteInit.readArgumentList()

????????????*?Presently?the?wire?format?to?the?zygote?process?is:

????????????*?a)?a?count?of?arguments?(argc,?in?essence)

????????????*?b)?a?number?of?newline-separated?argument?strings?equal?to?count

????????????*

????????????*?After?the?zygote?process?reads?these?it?will?write?the?pid?of

????????????*?the?child?or?-1?on?failure.

????????????*/

????????????sZygoteWriter.write(Integer.toString(args.size()));

????????????sZygoteWriter.newLine();

????????????int?sz?=?args.size();

????????????for?(int?i?=?0;?i?<?sz;?i++)?{

????????????????String?arg?=?args.get(i);

????????????????if?(arg.indexOf('\n')?>=?0)?{

????????????????????throw?new?ZygoteStartFailedEx("embedded?newlines?not?allowed");

????????????????}

????????????????sZygoteWriter.write(arg);

????????????????sZygoteWriter.newLine();

????????????}

????????????sZygoteWriter.flush();

????????????//?Should?there?be?a?timeout?on?this?

????????????pid?=?sZygoteInputStream.readInt();

????????????if?(pid?<?0)?{

????????????????throw?new?ZygoteStartFailedEx("fork()?failed");

????????????}

????????}?catch(IOException?ex)?{

????????......

????????}

????????return?pid;

????}

????......

}

?? ? ? ? 這里的sZygoteWriter是一個(gè)Socket寫(xiě)入流入撒,是由openZygoteSocketIfNeeded函數(shù)打開(kāi)的:

public?class?Process?{

????......

????/**

????*?Tries?to?open?socket?to?Zygote?process?if?not?already?open.?If

????*?already?open,?does?nothing.??May?block?and?retry.

????*/

????private?static?void?openZygoteSocketIfNeeded()?throws?ZygoteStartFailedEx?

????{

????????int?retryCount;

????????if(sPreviousZygoteOpenFailed)?{

????????????/*

????????????*?If?we've?failed?before,?expect?that?we'll?fail?again?and

????????????*?don't?pause?for?retries.

????????????*/

????????????retryCount?=?0;

????????}?else{

????????????retryCount?=?10;

????????}

????????/*

????????*?See?bug?#811181:?Sometimes?runtime?can?make?it?up?before?zygote.

????????*?Really,?we'd?like?to?do?something?better?to?avoid?this?condition,

????????*?but?for?now?just?wait?a?bit...

????????*/

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

????????{

????????????????if?(retry?>?0)?{

????????????????????try{

????????????????????????Log.i("Zygote",?"Zygote?not?up?yet,?sleeping...");

????????????????????????Thread.sleep(ZYGOTE_RETRY_MILLIS);

????????????????????}?catch(InterruptedException?ex)?{

????????????????????????//?should?never?happen

????????????????????}

????????????????}

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

????????????????????Log.i("Zygote",?"Process:?zygote?socket?opened");

????????????????????sPreviousZygoteOpenFailed?=?false;

????????????????????break;

????????????????}?catch(IOException?ex)?{

????????????????????......

????????????????}

????????????}

????????????......

????????}

????????......

????}

?? ? ? ?這個(gè)Socket由frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的ZygoteInit類(lèi)在runSelectLoopMode函數(shù)偵聽(tīng)的。


Step 5.?ZygoteInit.runSelectLoopMode

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

public?class?ZygoteInit?{

????......

????/**

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

????*

????*?@throws?MethodAndArgsCaller?in?a?child?process?when?a?main()?should

????*?be?executed.

????*/

????private?static?void?runSelectLoopMode()?throws?MethodAndArgsCaller?{

????????ArrayList?fds?=?new?ArrayList();

????????ArrayList?peers?=?new?ArrayList();

????????FileDescriptor[]?fdArray?=?new?FileDescriptor[4];

????????fds.add(sServerSocket.getFileDescriptor());

????????peers.add(null);

????????int?loopCount?=?GC_LOOP_COUNT;

????????while?(true)?{

????????????int?index;

????????????/*

????????????*?Call?gc()?before?we?block?in?select().

????????????*?It's?work?that?has?to?be?done?anyway,?and?it's?better

????????????*?to?avoid?making?every?child?do?it.??It?will?also

????????????*?madvise()?any?free?memory?as?a?side-effect.

????????????*

????????????*?Don't?call?it?every?time,?because?walking?the?entire

????????????*?heap?is?a?lot?of?overhead?to?free?a?few?hundred?bytes.

????????????*/

????????????if?(loopCount?<=?0)?{

????????????????gc();

????????????????loopCount?=?GC_LOOP_COUNT;

????????????}?else{

????????????????loopCount--;

????????????}

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

????????????????}

????????????}

????????}

????}

????......

}

?? ? ? ?當(dāng)Step 4將數(shù)據(jù)通過(guò)Socket接口發(fā)送出去后椭岩,就會(huì)下面這個(gè)語(yǔ)句:

done?=?peers.get(index).runOnce();

?? ? ? ?這里從peers.get(index)得到的是一個(gè)ZygoteConnection對(duì)象茅逮,表示一個(gè)Socket連接璃赡,因此,接下來(lái)就是調(diào)用ZygoteConnection.runOnce函數(shù)進(jìn)一步處理了献雅。


Step 6.?ZygoteConnection.runOnce

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:

class?ZygoteConnection?

{

????......

????boolean?runOnce()?throws?ZygoteInit.MethodAndArgsCaller?

????{

????????String?args[];

????????Arguments?parsedArgs?=?null;

????????FileDescriptor[]?descriptors;

????????try{

????????????args?=?readArgumentList();

????????????descriptors?=?mSocket.getAncillaryFileDescriptors();

????????}?catch(IOException?ex)?{

????????????......

????????????return?true;

????????}

????????......

????????/**?the?stderr?of?the?most?recent?request,?if?avail?*/

????????PrintStream?newStderr?=?null;

????????if?(descriptors?!=?null?&&?descriptors.length?>=?3)?{

????????????newStderr?=?new?PrintStream(new?FileOutputStream(descriptors[2]));

????????}

????????int?pid;

????????try{

????????????parsedArgs?=?new?Arguments(args);

????????????applyUidSecurityPolicy(parsedArgs,?peer);

????????????applyDebuggerSecurityPolicy(parsedArgs);

????????????applyRlimitSecurityPolicy(parsedArgs,?peer);

????????????applyCapabilitiesSecurityPolicy(parsedArgs,?peer);

????????????int[][]?rlimits?=?null;

????????????if?(parsedArgs.rlimits?!=?null)?{

????????????????rlimits?=?parsedArgs.rlimits.toArray(intArray2d);

????????????}

????????????pid?=?Zygote.forkAndSpecialize(parsedArgs.uid,?parsedArgs.gid, parsedArgs.gids,?parsedArgs.debugFlags,?rlimits);

????????}?catch(IllegalArgumentException?ex)?{

????????????......

????????}?catch(ZygoteSecurityException?ex)?{

????????????......

????????}

????????if?(pid?==?0)?{

????????????//?in?child

????????????handleChildProc(parsedArgs,?descriptors,?newStderr);

????????????//?should?never?happen

????????????return?true;

????????}?else?{?/*?pid?!=?0?*/

????????????//?in?parent...pid?of?<?0?means?failure

????????????return?handleParentProc(pid,?descriptors,?parsedArgs);

????????}

????}

????......

}

?? ? ? ? 真正創(chuàng)建進(jìn)程的地方就是在這里了:

pid?=?Zygote.forkAndSpecialize(parsedArgs.uid,?parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits);

?? ? ? ?有Linux開(kāi)發(fā)經(jīng)驗(yàn)的讀者很容易看懂這個(gè)函數(shù)調(diào)用碉考,這個(gè)函數(shù)會(huì)創(chuàng)建一個(gè)進(jìn)程,而且有兩個(gè)返回值挺身,一個(gè)是在當(dāng)前進(jìn)程中返回的侯谁,一個(gè)是在新創(chuàng)建的進(jìn)程中返回,即在當(dāng)前進(jìn)程的子進(jìn)程中返回章钾,在當(dāng)前進(jìn)程中的返回值就是新創(chuàng)建的子進(jìn)程的pid值墙贱,而在子進(jìn)程中的返回值是0。因?yàn)槲覀冎魂P(guān)心創(chuàng)建的新進(jìn)程的情況贱傀,因此惨撇,我們沿著子進(jìn)程的執(zhí)行路徑繼續(xù)看下去:

if?(pid?==?0)?{

????//?in?child

????handleChildProc(parsedArgs,?descriptors,?newStderr);

????//?should?never?happen

? ??return?true;

}?else?{?

????/*?pid?!=?0?*/

????......

}

?? ? ? ?這里就是調(diào)用handleChildProc函數(shù)了。


Step7.?ZygoteConnection.handleChildProc

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:

class?ZygoteConnection?{

?????......

????private?void?handleChildProc(Arguments?parsedArgs, FileDescriptor[]?descriptors, PrintStream?newStderr)?throws?ZygoteInit.MethodAndArgsCaller?

????{

????????......

????????if(parsedArgs.runtimeInit)?{

????????????RuntimeInit.zygoteInit(parsedArgs.remainingArgs);

????????}?else{

????????????......

????????}

????}

????......

}

?? ? ? ?由于在前面的Step 3中府寒,指定了"--runtime-init"參數(shù)魁衙,表示要為新創(chuàng)建的進(jìn)程初始化運(yùn)行時(shí)庫(kù),因此株搔,這里的parseArgs.runtimeInit值為true剖淀,于是就繼續(xù)執(zhí)行RuntimeInit.zygoteInit進(jìn)一步處理了。


Step 8.?RuntimeInit.zygoteInit

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

public?class?RuntimeInit?{

????......

????public?static?final?void?zygoteInit(String[]?argv)?throws?ZygoteInit.MethodAndArgsCaller?

????{

????????//?TODO:?Doing?this?here?works,?but?it?seems?kind?of?arbitrary.?Find

????????//?a?better?place.?The?goal?is?to?set?it?up?for?applications,?but?not

????????//?tools?like?am.

????????System.setOut(new?AndroidPrintStream(Log.INFO,?"System.out"));

????????System.setErr(new?AndroidPrintStream(Log.WARN,?"System.err"));

????????commonInit();

????????zygoteInitNative();

????????int?curArg?=?0;

????????for?(?/*?curArg?*/;?curArg?<?argv.length;?curArg++)?{

????????????String?arg?=?argv[curArg];

????????????if?(arg.equals("--"))?{

????????????????curArg++;

????????????????break;

????????????}?else?if?(!arg.startsWith("--"))?{

????????????????break;

????????????}?else?if?(arg.startsWith("--nice-name="))?{

????????????????String?niceName?=?arg.substring(arg.indexOf('=')?+?1);

????????????????Process.setArgV0(niceName);

????????????}

????????}

????????if(curArg?==?argv.length)?{

????????????Slog.e(TAG,?"Missing?classname?argument?to?RuntimeInit!");

????????????//?let?the?process?exit

????????????return;

????????}

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

????}

????......

}??

?? ? ? ?這里有兩個(gè)關(guān)鍵的函數(shù)調(diào)用纤房,一個(gè)是zygoteInitNative函數(shù)調(diào)用纵隔,一個(gè)是invokeStaticMain函數(shù)調(diào)用,前者就是執(zhí)行Binder驅(qū)動(dòng)程序初始化的相關(guān)工作了炮姨,正是由于執(zhí)行了這個(gè)工作巨朦,才使得進(jìn)程中的Binder對(duì)象能夠順利地進(jìn)行Binder進(jìn)程間通信,而后一個(gè)函數(shù)調(diào)用剑令,就是執(zhí)行進(jìn)程的入口函數(shù)糊啡,這里就是執(zhí)行startClass類(lèi)的main函數(shù)了,而這個(gè)startClass即是我們?cè)赟tep 1中傳進(jìn)來(lái)的"android.app.ActivityThread"值吁津,表示要執(zhí)行android.app.ActivityThread類(lèi)的main函數(shù)棚蓄。

?? ? ? ?我們先來(lái)看一下zygoteInitNative函數(shù)的調(diào)用過(guò)程,然后再回到RuntimeInit.zygoteInit函數(shù)中來(lái)碍脏,看看它是如何調(diào)用android.app.ActivityThread類(lèi)的main函數(shù)的梭依。


step 9.?RuntimeInit.zygoteInitNative

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

public?class?RuntimeInit?{

????......

????public?static?final?native?void?zygoteInitNative();

????......

}

?? ? ? ?這里可以看出,函數(shù)zygoteInitNative是一個(gè)Native函數(shù)典尾,實(shí)現(xiàn)在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

static?void?com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv*?env,?jobject?clazz)

{

????gCurRuntime->onZygoteInit();

}

?? ? ? ?這里它調(diào)用了全局變量gCurRuntime的onZygoteInit函數(shù)役拴,這個(gè)全局變量的定義在frameworks/base/core/jni/AndroidRuntime.cpp文件開(kāi)頭的地方:

static?AndroidRuntime*?gCurRuntime?=?NULL;

?? ? ? ?這里可以看出,它的類(lèi)型為AndroidRuntime钾埂,它是在AndroidRuntime類(lèi)的構(gòu)造函數(shù)中初始化的河闰,AndroidRuntime類(lèi)的構(gòu)造函數(shù)也是定義在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

AndroidRuntime::AndroidRuntime()

{

????......

????assert(gCurRuntime?==?NULL);????????//?one?per?process

????gCurRuntime?=?this;

}

?? ? ? ?那么這個(gè)AndroidRuntime類(lèi)的構(gòu)造函數(shù)又是什么時(shí)候被調(diào)用的呢科平?AndroidRuntime類(lèi)的聲明在frameworks/base/include/android_runtime/AndroidRuntime.h文件中,如果我們打開(kāi)這個(gè)文件會(huì)看到姜性,它是一個(gè)虛擬類(lèi)瞪慧,也就是我們不能直接創(chuàng)建一個(gè)AndroidRuntime對(duì)象,只能用一個(gè)AndroidRuntime類(lèi)的指針來(lái)指向它的某一個(gè)子類(lèi)部念,這個(gè)子類(lèi)就是AppRuntime了弃酌,它定義在frameworks/base/cmds/app_process/app_main.cpp文件中:

int?main(int?argc,?const?char*?constargv[])

{

????......

????AppRuntime?runtime;

????......

}

?? ? ? ?而AppRuntime類(lèi)繼續(xù)了AndroidRuntime類(lèi),它也是定義在frameworks/base/cmds/app_process/app_main.cpp文件中:

class?AppRuntime?:?public?AndroidRuntime

{

????......

};

?? ? ? ?因此儡炼,在前面的com_android_internal_os_RuntimeInit_zygoteInit函數(shù)妓湘,實(shí)際是執(zhí)行了AppRuntime類(lèi)的onZygoteInit函數(shù)险绘。


Step 10.?AppRuntime.onZygoteInit

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/cmds/app_process/app_main.cpp文件中:

class?AppRuntime?:?public?AndroidRuntime

{

????......

????virtual?void?onZygoteInit()

????{

????????sp?proc?=?ProcessState::self();

????????if(proc->supportsProcesses())?{

????????????LOGV("App?process:?starting?thread?pool.\n");

????????????proc->startThreadPool();

????????}

????}

????......

};

?? ? ? ?這里它就是調(diào)用ProcessState::startThreadPool啟動(dòng)線程池了惹骂,這個(gè)線程池中的線程就是用來(lái)和Binder驅(qū)動(dòng)程序進(jìn)行交互的了。


Step 11.?ProcessState.startThreadPool

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:

void?ProcessState::startThreadPool()

{

????AutoMutex?_l(mLock);

????if(!mThreadPoolStarted)?{

????????mThreadPoolStarted?=?true;

????????spawnPooledThread(true);

????}

}

?? ? ? ?ProcessState類(lèi)是Binder進(jìn)程間通信機(jī)制的一個(gè)基礎(chǔ)組件瑞佩,它的作用可以參考淺談Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server和Client獲得Service Manager接口之路楣责、Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過(guò)程源代碼分析Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Client獲得Server遠(yuǎn)程接口過(guò)程源代碼分析這三篇文章。這里它調(diào)用spawnPooledThread函數(shù)進(jìn)一步處理聂沙。


Step 12.?ProcessState.spawnPooledThread

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:

void?ProcessState::spawnPooledThread(bool?isMain)

{

????if(mThreadPoolStarted)?{

????????int32_t?s?=?android_atomic_add(1,?&mThreadPoolSeq);

????????char?buf[32];

????????sprintf(buf,?"Binder?Thread?#%d",?s);

????????LOGV("Spawning?new?pooled?thread,?name=%s\n",?buf);

????????sp?t?=?new?PoolThread(isMain);

????????t->run(buf);

????}

}??

?? ? ? ?這里它會(huì)創(chuàng)建一個(gè)PoolThread線程類(lèi)秆麸,然后執(zhí)行它的run函數(shù),最終就會(huì)執(zhí)行PoolThread類(lèi)的threadLoop函數(shù)了及汉。


Step 13.?PoolThread.threadLoop

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/libs/binder/ProcessState.cpp文件中:

class?PoolThread?:?public?Thread

{

? ??public:

????????PoolThread(bool?isMain) :?mIsMain(isMain)

????????{

????????}

? ??protected:

????????virtual?bool?threadLoop()

????????{

????????????IPCThreadState::self()->joinThreadPool(mIsMain);

????????????return?false;

????????}

????????const?bool?mIsMain;

};

?? ? ? ?這里它執(zhí)行了IPCThreadState::joinThreadPool函數(shù)進(jìn)一步處理沮趣。IPCThreadState也是Binder進(jìn)程間通信機(jī)制的一個(gè)基礎(chǔ)組件,它的作用可以參考淺談Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server和Client獲得Service Manager接口之路坷随、Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過(guò)程源代碼分析Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Client獲得Server遠(yuǎn)程接口過(guò)程源代碼分析這三篇文章房铭。


Step14.?IPCThreadState.joinThreadPool

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/libs/binder/IPCThreadState.cpp文件中:

void?IPCThreadState::joinThreadPool(bool?isMain)

{

????......

????mOut.writeInt32(isMain???BC_ENTER_LOOPER?:?BC_REGISTER_LOOPER);

????......

????status_t?result;

????do{

????????int32_t?cmd;

????????......

????????//?now?get?the?next?command?to?be?processed,?waiting?if?necessary

????????result?=?talkWithDriver();

????????if(result?>=?NO_ERROR)?{

????????????size_t?IN?=?mIn.dataAvail();

????????????if?(IN?<?sizeof(int32_t))?continue;

????????????cmd?=?mIn.readInt32();

????????????......

????????????result?=?executeCommand(cmd);

????????}

???????......

????}?while(result?!=?-ECONNREFUSED?&&?result?!=?-EBADF);

????......

????mOut.writeInt32(BC_EXIT_LOOPER);

????talkWithDriver(false);

}

?? ? ? ?這個(gè)函數(shù)首先告訴Binder驅(qū)動(dòng)程序,這條線程要進(jìn)入循環(huán)了:

mOut.writeInt32(isMain???BC_ENTER_LOOPER?:?BC_REGISTER_LOOPER);

?? ? ? ?然后在中間的while循環(huán)中通過(guò)talkWithDriver不斷與Binder驅(qū)動(dòng)程序進(jìn)行交互温眉,以便獲得Client端的進(jìn)程間調(diào)用:

result?=?talkWithDriver();

?? ? ? ?獲得了Client端的進(jìn)程間調(diào)用后缸匪,就調(diào)用excuteCommand函數(shù)來(lái)處理這個(gè)請(qǐng)求:

result?=?executeCommand(cmd);

?? ? ? ?最后,線程退出時(shí)类溢,也會(huì)告訴Binder驅(qū)動(dòng)程序凌蔬,它退出了,這樣Binder驅(qū)動(dòng)程序就不會(huì)再在Client端的進(jìn)程間調(diào)用分發(fā)給它了:

mOut.writeInt32(BC_EXIT_LOOPER);

talkWithDriver(false);

?? ? ? ?我們?cè)賮?lái)看看talkWithDriver函數(shù)的實(shí)現(xiàn)闯冷。


Step 15. talkWithDriver

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/libs/binder/IPCThreadState.cpp文件中:

status_t?IPCThreadState::talkWithDriver(bool?doReceive)

{

????......

????binder_write_read?bwr;

????//?Is?the?read?buffer?empty?

????const?bool?needRead?=?mIn.dataPosition()?>=?mIn.dataSize();

????//?We?don't?want?to?write?anything?if?we?are?still?reading

????//?from?data?left?in?the?input?buffer?and?the?caller

????//?has?requested?to?read?the?next?data.

????const?size_toutAvail?=?(!doReceive?||?needRead)???mOut.dataSize()?:?0;

????bwr.write_size?=?outAvail;

????bwr.write_buffer?=?(long?unsigned?int)mOut.data();

????//?This?is?what?we'll?read.

????if(doReceive?&&?needRead)?{

????????bwr.read_size?=?mIn.dataCapacity();

????????bwr.read_buffer?=?(long?unsigned?int)mIn.data();

????}?else{

????????bwr.read_size?=?0;

????}

????......

????//?Return?immediately?if?there?is?nothing?to?do.

????if?((bwr.write_size?==?0)?&&?(bwr.read_size?==?0))?

? ??????return?NO_ERROR;

????bwr.write_consumed?=?0;

????bwr.read_consumed?=?0;

????status_t?err;

????do{

????????......

#if?defined(HAVE_ANDROID_OS)

????????if(ioctl(mProcess->mDriverFD,?BINDER_WRITE_READ,?&bwr)?>=?0)

????????????err?=?NO_ERROR;

????????else

????????????err?=?-errno;

#else

????????????err?=?INVALID_OPERATION;

#endif

????????????......

????????}

????}?while(err?==?-EINTR);

????....

????if(err?>=?NO_ERROR)?{

????????if(bwr..write_consumed?>?0)?{

????????????if(bwr.write_consumed?<?(ssize_t)mOut.dataSize())

????????????????mOut.remove(0,?bwr.write_consumed);

????????????else

????????????????mOut.setDataSize(0);

????????}

????????if(bwr.read_consumed?>?0)?{

????????????mIn.setDataSize(bwr.read_consumed);

????????????mIn.setDataPosition(0);

????????}

????????......

????????return?NO_ERROR;

????}

????return?err;

}

?? ? ? ?這個(gè)函數(shù)的具體作用可以參考Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過(guò)程源代碼分析一文砂心,它只要就是通過(guò)ioctl文件操作函數(shù)來(lái)和Binder驅(qū)動(dòng)程序交互的了:

ioctl(mProcess->mDriverFD,?BINDER_WRITE_READ,?&bwr)

? ? ????有了這個(gè)線程池之后,我們?cè)陂_(kāi)發(fā)Android應(yīng)用程序的時(shí)候蛇耀,當(dāng)我們要和其它進(jìn)程中進(jìn)行通信時(shí)辩诞,只要定義自己的Binder對(duì)象,然后把這個(gè)Binder對(duì)象的遠(yuǎn)程接口通過(guò)其它途徑傳給其它進(jìn)程后纺涤,其它進(jìn)程就可以通過(guò)這個(gè)Binder對(duì)象的遠(yuǎn)程接口來(lái)調(diào)用我們的應(yīng)用程序進(jìn)程的函數(shù)了译暂,它不像我們?cè)贑++層實(shí)現(xiàn)Binder進(jìn)程間通信機(jī)制的Server時(shí)抠忘,必須要手動(dòng)調(diào)用IPCThreadState.joinThreadPool函數(shù)來(lái)進(jìn)入一個(gè)無(wú)限循環(huán)中與Binder驅(qū)動(dòng)程序交互以便獲得Client端的請(qǐng)求,這樣就實(shí)現(xiàn)了我們?cè)谖恼麻_(kāi)頭處說(shuō)的Android應(yīng)用程序進(jìn)程天然地支持Binder進(jìn)程間通信機(jī)制秧秉。

?? ? ? ?細(xì)心的讀者可能會(huì)發(fā)現(xiàn)褐桌,從Step 1到Step 9,都是在Android應(yīng)用程序框架層運(yùn)行的象迎,而從Step 10到Step 15荧嵌,都是在Android系統(tǒng)運(yùn)行時(shí)庫(kù)層運(yùn)行的,這兩個(gè)層次中的Binder進(jìn)程間通信機(jī)制的接口一個(gè)是用Java來(lái)實(shí)現(xiàn)的砾淌,而另一個(gè)是用C++來(lái)實(shí)現(xiàn)的啦撮,這兩者是如何協(xié)作的呢?這就是通過(guò)JNI層來(lái)實(shí)現(xiàn)的了汪厨,具體可以參考Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼分析一文赃春。

?? ? ? ?回到Step 8中的RuntimeInit.zygoteInit函數(shù)中,在初始化完成Binder進(jìn)程間通信機(jī)制的基礎(chǔ)設(shè)施后劫乱,它接著就要進(jìn)入進(jìn)程的入口函數(shù)了织中。


Step 16.?RuntimeInit.invokeStaticMain

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

public?class?ZygoteInit?{

????......

????static?void?invokeStaticMain(ClassLoader?loader, String?className,?String[]?argv)?throws?ZygoteInit.MethodAndArgsCaller?

????{

????????Class?cl;

????????try{

????????????cl?=?loader.loadClass(className);

????????}?catch(ClassNotFoundException?ex)?{

????????????......

????????}

????????Method?m;

????????try{

????????????m?=?cl.getMethod("main",?new?Class[]?{?String[].class});

????????}?catch(NoSuchMethodException?ex)?{

????????????......

????????}?catch(SecurityException?ex)?{

????????????......

????????}

????????int?modifiers?=?m.getModifiers();

????????......

????????/*

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

????}

????......

}

?? ? ? ?前面我們說(shuō)過(guò),這里傳進(jìn)來(lái)的參數(shù)className字符串值為"android.app.ActivityThread"衷戈,這里就通ClassLoader.loadClass函數(shù)將它加載到進(jìn)程中:

cl?=?loader.loadClass(className);

?? ? ? ?然后獲得它的靜態(tài)成員函數(shù)main:

m?=?cl.getMethod("main",?new?Class[]?{?String[].class});

?? ? ? ?函數(shù)最后并沒(méi)有直接調(diào)用這個(gè)靜態(tài)成員函數(shù)main狭吼,而是通過(guò)拋出一個(gè)異常ZygoteInit.MethodAndArgsCaller,然后讓ZygoteInit.main函數(shù)在捕獲這個(gè)異常的時(shí)候再調(diào)用android.app.ActivityThread類(lèi)的main函數(shù)殖妇。為什么要這樣做呢刁笙?注釋里面已經(jīng)講得很清楚了,它是為了清理堆棧的谦趣,這樣就會(huì)讓android.app.ActivityThread類(lèi)的main函數(shù)覺(jué)得自己是進(jìn)程的入口函數(shù)疲吸,而事實(shí)上,在執(zhí)行android.app.ActivityThread類(lèi)的main函數(shù)之前前鹅,已經(jīng)做了大量的工作了摘悴。


?? ? ? ?我們看看ZygoteInit.main函數(shù)在捕獲到這個(gè)異常的時(shí)候做了什么事:

public?class?ZygoteInit?{

????......

????public?static?void?main(String?argv[])?{

????????try{

????????????......

????????}?catch(MethodAndArgsCaller?caller)?{

????????????caller.run();

????????}?catch(RuntimeException?ex)?{

????????????......

????????}

????}

????......

}

?? ? ? ?它執(zhí)行MethodAndArgsCaller的run函數(shù):

public?class?ZygoteInit?{

????......

????public?static?class?MethodAndArgsCaller?extends?Exception?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?});

????????????}?catch(IllegalAccessException?ex)?{

????????????????......

????????????}?catch(InvocationTargetException?ex)?{

????????????????......

????????????}

????????}

????}

????......

}

?? ? ? ?這里的成員變量mMethod和mArgs都是在前面構(gòu)造異常對(duì)象時(shí)傳進(jìn)來(lái)的,這里的mMethod就對(duì)應(yīng)android.app.ActivityThread類(lèi)的main函數(shù)了舰绘,于是最后就通過(guò)下面語(yǔ)句執(zhí)行這個(gè)函數(shù):

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

?? ? ? ?這樣烦租,android.app.ActivityThread類(lèi)的main函數(shù)就被執(zhí)行了。


Step 17.?ActivityThread.main

?? ? ? ?這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public?final?class?ActivityThread?{

????......

????public?static?final?void?main(String[]?args)?

????{

????????SamplingProfilerIntegration.start();

????????Process.setArgV0("");

????????Looper.prepareMainLooper();

????????if?(sMainThreadHandler?==?null)?{

????????????sMainThreadHandler?=?new?Handler();

????????}

????????ActivityThread?thread?=?new?ActivityThread();

????????thread.attach(false);

????????if?(false)?{

????????????Looper.myLooper().setMessageLogging(new?LogPrinter(Log.DEBUG,?"ActivityThread"));

????????}

????????Looper.loop();

????????if(Process.supportsProcesses())?{

????????????throw?new?RuntimeException("Main?thread?loop?unexpectedly?exited");

????????}

????????thread.detach();

????????String?name?=?(thread.mInitialApplication?!=?null) ??thread.mInitialApplication.getPackageName()

????????????:?"";

????????Slog.i(TAG,?"Main?thread?of?"?+?name?+?"?is?now?exiting");

????}

????......

}

?? ? ? ?從這里我們可以看出除盏,這個(gè)函數(shù)首先會(huì)在進(jìn)程中創(chuàng)建一個(gè)ActivityThread對(duì)象:

ActivityThread?thread?=?new?ActivityThread();

?? ? ? ?然后進(jìn)入消息循環(huán)中:

Looper.loop();

?? ? ? ?這樣叉橱,我們以后就可以在這個(gè)進(jìn)程中啟動(dòng)Activity或者Service了。


? ? ?至此者蠕,Android應(yīng)用程序進(jìn)程啟動(dòng)過(guò)程的源代碼就分析完成了窃祝,它除了指定新的進(jìn)程的入口函數(shù)是ActivityThread的main函數(shù)之外,還為進(jìn)程內(nèi)的Binder對(duì)象提供了Binder進(jìn)程間通信機(jī)制的基礎(chǔ)設(shè)施踱侣,由此可見(jiàn)粪小,Binder進(jìn)程間通信機(jī)制在Android系統(tǒng)中是何等的重要大磺,而且是無(wú)處不在,想進(jìn)一步學(xué)習(xí)Android系統(tǒng)的Binder進(jìn)程間通信機(jī)制探膊,請(qǐng)參考Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文杠愧。

2 進(jìn)程創(chuàng)建

Android系統(tǒng)中的進(jìn)程管理:進(jìn)程的創(chuàng)建

http://mobile.51cto.com/android-520139.htm

2.1 概述

????????Android系統(tǒng)以Linux內(nèi)核為基礎(chǔ),所以對(duì)于進(jìn)程的管理自然離不開(kāi)Linux本身提供的機(jī)制逞壁。例如:

????· 通過(guò)fork來(lái)創(chuàng)建進(jìn)行

????· 通過(guò)信號(hào)量來(lái)管理進(jìn)程

????· 通過(guò)proc文件系統(tǒng)來(lái)查詢(xún)和調(diào)整進(jìn)程狀態(tài)等

????????對(duì)于Android來(lái)說(shuō)流济,進(jìn)程管理的主要內(nèi)容包括以下幾個(gè)部分內(nèi)容:

????· 進(jìn)程的創(chuàng)建

????· 進(jìn)程的優(yōu)先級(jí)管理

????· 進(jìn)程的內(nèi)存管理

????· 進(jìn)程的回收和死亡處理

????????本文會(huì)專(zhuān)門(mén)講解進(jìn)程的創(chuàng)建,其余部分將在后面的文章中講解腌闯。


2.2 主要模塊

??? ????為了便于下文的講解绳瘟,這里先介紹一下Android系統(tǒng)中牽涉到進(jìn)程創(chuàng)建的幾個(gè)主要模塊。同時(shí)為了便于讀者更詳細(xì)的了解這些模塊姿骏,這里也同時(shí)提供了這些模塊的代碼路徑糖声。

??? ????這里提到的代碼路徑是指AOSP的源碼數(shù)中的路徑。

??????? 關(guān)于如何獲取AOSP源碼請(qǐng)參見(jiàn)這里:Downloading the Source分瘦。

? ??????本文以Android N版本的代碼為示例蘸泻,所用到的Source Code Tags是:android-7.0.0_r1。

相關(guān)模塊:

????· app_process

代碼路徑:frameworks/base/cmds/app_process

??? ????說(shuō)明:app_process是一個(gè)可執(zhí)行程序嘲玫,該程序的主要作用是啟動(dòng)zygote和system_server進(jìn)程悦施。

????· Zygote

代碼路徑:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

??? ????說(shuō)明:zygote進(jìn)程是所有應(yīng)用進(jìn)程的父進(jìn)程,這是系統(tǒng)中一個(gè)非常重要的進(jìn)程趁冈,下文我們會(huì)詳細(xì)講解歼争。

[if !supportLists]·??????[endif]ActivityManager

代碼路徑:frameworks/base/services/core/java/com/android/server/am/

??? 說(shuō)明:am是ActivityManager的縮寫(xiě)拜马。

??? ????這個(gè)目錄下的代碼負(fù)責(zé)了Android全部四大組件(Activity渗勘,Service,ContentProvider俩莽,BroadcastReceiver)的管理旺坠,并且還掌控了所有應(yīng)用程序進(jìn)程的創(chuàng)建和進(jìn)程的優(yōu)先級(jí)管理。

??? ????因此扮超,這個(gè)部分的內(nèi)容將是本系列文章講解的重點(diǎn)取刃。


2.3 關(guān)于進(jìn)程

??? ????在Android系統(tǒng)中,進(jìn)程可以大致分為系統(tǒng)進(jìn)程和應(yīng)用進(jìn)程兩大類(lèi)出刷。

??? ????系統(tǒng)進(jìn)程是系統(tǒng)內(nèi)置的(例如:init璧疗,zygote,system_server進(jìn)程)馁龟,屬于操作系統(tǒng)必不可少的一部分崩侠。系統(tǒng)進(jìn)程的作用在于:

????· 管理硬件設(shè)備

????· 提供訪問(wèn)設(shè)備的基本能力

????· 管理應(yīng)用進(jìn)程

??? ????應(yīng)用進(jìn)程是指應(yīng)用程序運(yùn)行的進(jìn)程。這些應(yīng)用程序可能是系統(tǒng)出廠自帶的(例如Launcher坷檩,電話却音,短信等應(yīng)用)改抡,也可能是用戶自己安裝的(例如:微信,支付寶等)系瓢。

??? ????系統(tǒng)進(jìn)程的數(shù)量通常是固定的(出廠或者系統(tǒng)升級(jí)之后就確定了)阿纤,并且系統(tǒng)進(jìn)程通常是一直存活,常駐內(nèi)存的夷陋。系統(tǒng)進(jìn)程的異常退出將可能導(dǎo)致設(shè)備無(wú)法正常使用欠拾。

??? ????而應(yīng)用程序和應(yīng)用進(jìn)程在每個(gè)人使用的設(shè)備上通常是各不一樣的。如何管理好這些不確定的應(yīng)用進(jìn)程肌稻,就是操作系統(tǒng)本身要仔細(xì)考慮的內(nèi)容清蚀。也是衡量一個(gè)操作系統(tǒng)好壞的標(biāo)準(zhǔn)之一。

??? ????在本文中爹谭,我們會(huì)介紹init枷邪,zygote和system_server三個(gè)系統(tǒng)進(jìn)程。

????????除此之外诺凡,本系列文章將會(huì)把主要精力集中在講解Android系統(tǒng)如何管理應(yīng)用進(jìn)程上东揣。


2.4 init進(jìn)程(核心)

??? ????init進(jìn)程是一切的開(kāi)始,在Android系統(tǒng)中腹泌,所有進(jìn)程的進(jìn)程號(hào)都是不確定的嘶卧,唯獨(dú)init進(jìn)程的進(jìn)程號(hào)一定是1。因?yàn)檫@個(gè)進(jìn)程一定是系統(tǒng)起來(lái)的第一個(gè)進(jìn)程凉袱。并且芥吟,init進(jìn)程掌控了整個(gè)系統(tǒng)的啟動(dòng)邏輯。

??????? 我們知道专甩,Android可能運(yùn)行在各種不同的平臺(tái)钟鸵,不同的設(shè)備上。因此涤躲,啟動(dòng)的邏輯是不盡相同的棺耍。為了適應(yīng)各種平臺(tái)和設(shè)備的需求,init進(jìn)程的初始化工作通過(guò)init.rc配置文件來(lái)管理种樱。你可以在AOSP源碼的system/core/rootdir/路徑找到這些配置文件蒙袍。配置文件的主入口文件是init.rc,這個(gè)文件會(huì)通過(guò)import引入其他幾個(gè)文件嫩挤。

??????? 在本文中害幅,我們統(tǒng)稱(chēng)這些文件為init.rc。init.rc通過(guò)Android Init Language來(lái)進(jìn)行配置岂昭。

??????? 建議讀者大致閱讀一下其語(yǔ)法說(shuō)明 以现。

??????? init.rc中配置了系統(tǒng)啟動(dòng)的時(shí)候該做哪些事情,以及啟動(dòng)哪些系統(tǒng)進(jìn)程。

????????這其中有兩個(gè)特別重要的進(jìn)程就是:zygote和system_server進(jìn)程叼风。

????· zygote的中文意思是“受精卵“取董。這是一個(gè)很有寓意的名稱(chēng):所有的應(yīng)用進(jìn)程都是由zygote fork出來(lái)的子進(jìn)程,因此zygote進(jìn)程是所有應(yīng)用進(jìn)程的父進(jìn)程无宿。

????· system_server 這個(gè)進(jìn)程正如其名稱(chēng)一樣茵汰,這是一個(gè)系統(tǒng)服務(wù)器。Framework層的幾乎所有服務(wù)都位于這個(gè)進(jìn)程中孽鸡。這其中就包括管理四大組件的ActivityManagerService蹂午。


2.5 Zygote進(jìn)程

??? ????init.rc文件會(huì)根據(jù)平臺(tái)不一樣,選擇下面幾個(gè)文件中的一個(gè)來(lái)啟動(dòng)zygote進(jìn)程:

????· init.zygote32.rc

????· init.zygote32_64.rc

????· init.zygote64.rc

????· init.zygote64_32.rc

??? ????這幾個(gè)文件的內(nèi)容是大致一致的彬碱,僅僅是為了不同平臺(tái)服務(wù)的豆胸。這里我們以init.zygote32.rc的文件為例,來(lái)看看其中的內(nèi)容:

service zygote/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

class main


socket zygote stream 660root system

onrestart write/sys/android_power/request_state wake

onrestart write/sys/power/state on

onrestart restartaudioserver

onrestart restartcameraserver

onrestart restart media

onrestart restart netd


writepid/dev/cpuset/foreground/tasks /dev/stune/foreground/tasks


??? ????在這段配置文件中(如果你不明白這段配置的含義巷疼,請(qǐng)閱讀一下文檔:Android Init Language)晚胡,啟動(dòng)了一個(gè)名稱(chēng)叫做zygote的服務(wù)進(jìn)程耕魄。這個(gè)進(jìn)程是通過(guò)/system/bin/app_process這個(gè)可執(zhí)行程序創(chuàng)建的逢艘。

??? ????并且在啟動(dòng)這個(gè)可執(zhí)行程序的時(shí)候,傳遞了`-Xzygote/system/bin --zygote --start-system-server

??? class main`這些參數(shù)剔氏。

??? ????要知道這里到底做了什么骡尽,我們需要看一下app_process的源碼遣妥。app_process的源碼在這個(gè)路徑:frameworks/base/cmds/app_process/app_main.cpp。????

??????? 這個(gè)文件的main函數(shù)的有如下代碼:

int main(int argc, char*const argv[])

{

??? ...

??? while (i < argc) {

??????? const char* arg = argv[i++];

??????? if (strcmp(arg, "--zygote")== 0) {

??????????? zygote = true;

??????????? niceName = ZYGOTE_NICE_NAME;

??????? } else if (strcmp(arg,"--start-system-server") == 0) {

??????????? startSystemServer = true;

??????? ...

??? }

??? ...

?? if (!className.isEmpty()) {

??????? ...

??? } else {

?????? ...


?????? if (startSystemServer) {

??????????args.add(String8("start-system-server"));

?????? }

??? }

??? ...

??? if (zygote) {

???????runtime.start("com.android.internal.os.ZygoteInit", args,zygote);

??? } else if (className) {

??????? runtime.start("com.android.internal.os.RuntimeInit",args, zygote);

??? } else {

??????? fprintf(stderr, "Error: no classname or --zygote supplied.\n");

??????? app_usage();

??????? LOG_ALWAYS_FATAL("app_process: noclass name or --zygote supplied.");

??????? return 10;

??? }

}?

????????這里會(huì)判斷攀细,

????· 如果執(zhí)行這個(gè)命令時(shí)帶了--zygote參數(shù)箫踩,就會(huì)通過(guò)runtime.start啟動(dòng)com.android.internal.os.ZygoteInit。

????· 如果參數(shù)中帶有--start-system-server參數(shù)谭贪,就會(huì)將start-system-server添加到args中境钟。

??????? 這段代碼是C++實(shí)現(xiàn)的。在執(zhí)行這段代碼的時(shí)候還沒(méi)有任何Java的環(huán)境故河。而runtime.start就是啟動(dòng)Java虛擬機(jī)吱韭,并在虛擬機(jī)中啟動(dòng)指定的類(lèi)吆豹。于是接下來(lái)的邏輯就在ZygoteInit.java中了鱼的。

??????? 這個(gè)文件的main函數(shù)主要代碼如下:

public static voidmain(String argv[]) {

?? ...

?? try {

?????? ...

?????? boolean startSystemServer = false;

?????? String socketName = "zygote";

?????? String abiList = null;

?????? for (int i = 1; i < argv.length; i++){

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

?????????????? startSystemServer = true;

?????????? } else if(argv[i].startsWith(ABI_LIST_ARG)) {

?????????????? ...

?????????? }

?????? }

?????? ...

?????? registerZygoteSocket(socketName);

?????? ...

?????? preload();

?????? ...

?????? Zygote.nativeUnmountStorageOnInit();

??????ZygoteHooks.stopZygoteNoThreadCreation();


?????? if (startSystemServer) {

?????????? startSystemServer(abiList,socketName);

?????? }


?????? Log.i(TAG, "Accepting commandsocket connections");

?????? runSelectLoop(abiList);

?????? closeServerSocket();

?? } catch (MethodAndArgsCaller caller) {

?????? caller.run();

?? } catch (RuntimeException ex) {

?????? Log.e(TAG, "Zygote died withexception", ex);

?????? closeServerSocket();

?????? throw ex;

?? }

}?

? 在這段代碼中,我們主要關(guān)注如下幾行:

????1. 通過(guò) registerZygoteSocket(socketName); 注冊(cè)Zygote Socket

????2. 通過(guò) preload(); 預(yù)先加載所有應(yīng)用都需要的公共資源

????3. 通過(guò) startSystemServer(abiList, socketName); 啟動(dòng)system_server

????4. 通過(guò) runSelectLoop(abiList); 在Looper上等待連接

??? ????這里需要說(shuō)明的是:zygote進(jìn)程啟動(dòng)之后痘煤,會(huì)啟動(dòng)一個(gè)socket套接字凑阶,并通過(guò)Looper一直在這個(gè)套接字上等待連接。

??? ????所有應(yīng)用進(jìn)程都是通過(guò)發(fā)送數(shù)據(jù)到這個(gè)套接字上衷快,然后由zygote進(jìn)程創(chuàng)建的宙橱。

??????? 這里還有一點(diǎn)說(shuō)明的是:

??????? 在Zygote進(jìn)程中,會(huì)通過(guò)preload函數(shù)加載需要應(yīng)用程序都需要的公共資源。

??????? 預(yù)先加載這些公共資源有如下兩個(gè)好處:

????· 加快應(yīng)用的啟動(dòng)速度 因?yàn)檫@些資源已經(jīng)在zygote進(jìn)程啟動(dòng)的時(shí)候加載好了

????· 通過(guò)共享的方式節(jié)省內(nèi)存 這是Linux本身提供的機(jī)制:父進(jìn)程已經(jīng)加載的內(nèi)容可以在子進(jìn)程中進(jìn)行共享师郑,而不用多份數(shù)據(jù)拷貝(除非子進(jìn)程對(duì)這些數(shù)據(jù)進(jìn)行了修改环葵。)

??? ????preload的資源主要是Framework相關(guān)的一些基礎(chǔ)類(lèi)和Resource資源,而這些資源正是所有應(yīng)用都需要的:

??? ????開(kāi)發(fā)者通過(guò)Android SDK開(kāi)發(fā)應(yīng)用所調(diào)用的API實(shí)現(xiàn)都在Framework中宝冕。

static void preload() {

?? Log.d(TAG,"begin preload");

?? Trace.traceBegin(Trace.TRACE_TAG_DALVIK,"BeginIcuCachePinning");

??beginIcuCachePinning();

??Trace.traceEnd(Trace.TRACE_TAG_DALVIK);


?? Trace.traceBegin(Trace.TRACE_TAG_DALVIK,"PreloadClasses");

?? preloadClasses();

??Trace.traceEnd(Trace.TRACE_TAG_DALVIK);


??Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");

??preloadResources();

??Trace.traceEnd(Trace.TRACE_TAG_DALVIK);


??Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");

?? preloadOpenGL();

??Trace.traceEnd(Trace.TRACE_TAG_DALVIK);


??preloadSharedLibraries();

??preloadTextResources();


??WebViewFactory.prepareWebViewInZygote();

??endIcuCachePinning();

??warmUpJcaProviders();

?? Log.d(TAG,"end preload");

}?


2.6 system_server進(jìn)程

??? ????上文已經(jīng)提到张遭,zygote進(jìn)程起來(lái)之后會(huì)根據(jù)需要啟動(dòng)system_server進(jìn)程。system_server進(jìn)程中包含了大量的系統(tǒng)服務(wù)地梨。例如:

????· 負(fù)責(zé)網(wǎng)絡(luò)管理的NetworkManagementService菊卷;

????· 負(fù)責(zé)窗口管理的WindowManagerService;

????· 負(fù)責(zé)震動(dòng)管理的VibratorService宝剖;

????· 負(fù)責(zé)輸入管理的InputManagerService洁闰;

??? ????等等。關(guān)于system_server万细,我們今后會(huì)其他的文章中專(zhuān)門(mén)講解扑眉,這里不做過(guò)多說(shuō)明。

??????? 在本文中赖钞,我們只關(guān)注system_server中的ActivityManagerService這個(gè)系統(tǒng)服務(wù)襟雷。


2.7 ActivityManagerService

??? ????上文中提到:zygote進(jìn)程在啟動(dòng)之后會(huì)啟動(dòng)一個(gè)socket,然后一直在這個(gè)socket等待連接仁烹。而會(huì)連接它的就是ActivityManagerService耸弄。因?yàn)锳ctivityManagerService掌控了所有應(yīng)用進(jìn)程的創(chuàng)建。所有應(yīng)用程序的進(jìn)程都是由ActivityManagerService通過(guò)socket發(fā)送請(qǐng)求給Zygote進(jìn)程卓缰,然后由zygote fork創(chuàng)建的计呈。

??? ????ActivityManagerService通過(guò)Process.start方法來(lái)請(qǐng)求zygote創(chuàng)建進(jìn)程:

public static finalProcessStartResult 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[]zygoteArgs)

{

?? try {

?????? return startViaZygote(processClass,niceName, uid, gid, gids,

?????????????? debugFlags, mountExternal, targetSdkVersion, seInfo,

?????????????? abi, instructionSet, appDataDir,zygoteArgs);

?? } catch (ZygoteStartFailedEx ex) {

?????? Log.e(LOG_TAG, "Starting VM processthrough Zygote failed");

?????? throw newRuntimeException("Starting VM process through Zygote failed", ex);

?? }

}?

??? ????這個(gè)函數(shù)會(huì)將啟動(dòng)進(jìn)程所需要的參數(shù)組裝好,并通過(guò)socket發(fā)送給zygote進(jìn)程征唬。然后zygote進(jìn)程根據(jù)發(fā)送過(guò)來(lái)的參數(shù)將進(jìn)程fork出來(lái)捌显。

??????? 在ActivityManagerService中,調(diào)用Process.start的地方是下面這個(gè)方法:

private final void startProcessLocked(ProcessRecord app, String hostingType,

?????? String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)?

{

? ? ...

????Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal,?app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,? app.info.dataDir, entryPointArgs);

? ? ...

}?

??? ????下文中我們會(huì)看到总寒,所有四大組件進(jìn)程的創(chuàng)建扶歪,都是調(diào)用這里的startProcessLocked這個(gè)方法而創(chuàng)建的。

??? ????對(duì)于每一個(gè)應(yīng)用進(jìn)程摄闸,在ActivityManagerService中善镰,都有一個(gè)ProcessRecord與之對(duì)應(yīng)。這個(gè)對(duì)象記錄了應(yīng)用進(jìn)程的所有詳細(xì)狀態(tài)年枕。

??????? PS:對(duì)于ProcessRecord的內(nèi)部結(jié)構(gòu)炫欺,在下一篇文章中,我們會(huì)講解熏兄。

??? ????為了查找方便品洛,對(duì)于每個(gè)ProcessRecord會(huì)存在下面兩個(gè)集合中树姨。

????· 按名稱(chēng)和uid組織的集合:

/**?

*?All?of?the?applications?we?currently?have?running?organized?by?name.?

*?The?keys?are?strings?of?the?application?package?name?(as?

*?returned?by?the?package?manager),?and?the?keys?are?ApplicationRecord?

*?objects.?

*/?

final?ProcessMap?mProcessNames?=?new?ProcessMap();?


· 按pid組織的集合:

/**?

*?All?of?the?processes?we?currently?have?running?organized?by?pid.?

*?The?keys?are?the?pid?running?the?application.?

?* NOTE:?This?object?is?protected?by?its?own?lock,?NOT?the?global?

*?activity?manager?lock!?

*/?

final?SparseArray?mPidsSelfLocked?=?new?SparseArray();?

????????下面這幅圖小節(jié)了上文的這些內(nèi)容:


2.8 關(guān)于應(yīng)用組件

Processes and Threads 提到:

??? ????“當(dāng)某個(gè)應(yīng)用組件啟動(dòng)且該應(yīng)用沒(méi)有運(yùn)行其他任何組件時(shí),Android 系統(tǒng)會(huì)使用單個(gè)執(zhí)行線程為應(yīng)用啟動(dòng)新的 Linux 進(jìn)程桥状∶本荆”

??? ????因此,四大組件中的任何一個(gè)先起來(lái)都會(huì)導(dǎo)致應(yīng)用進(jìn)程的創(chuàng)建辅斟。下文我們就詳細(xì)看一下台丛,它們啟動(dòng)時(shí),各自是如何導(dǎo)致應(yīng)用進(jìn)程的創(chuàng)建的砾肺。

??? ????PS:四大組件的管理本身又是一個(gè)比較大的話題挽霉,限于篇幅關(guān)系,這里不會(huì)非常深入的講解变汪,這里主要是講解四大組件與進(jìn)程創(chuàng)建的關(guān)系侠坎。

??? ????在應(yīng)用程序中,開(kāi)發(fā)者通過(guò):

????· startActivity(Intent intent) 來(lái)啟動(dòng)Activity

????· startService(Intent service) 來(lái)啟動(dòng)Service

????· sendBroadcast(Intent intent) 來(lái)發(fā)送廣播

????· ContentResolver 中的接口來(lái)使用ContentProvider

??? ????這其中裙盾,startActivity实胸,startService和sendBroadcast還有一些重載方法。

??????? 其實(shí)這里提到的所有這些方法番官,最終都是通過(guò)Binder調(diào)用到ActivityManagerService中庐完,由其進(jìn)行處理的。

??? ????這里特別說(shuō)明一下:應(yīng)用進(jìn)程和ActivityManagerService所在進(jìn)程(即system_server進(jìn)程)是相互獨(dú)立的徘熔,兩個(gè)進(jìn)程之間的方法通常是不能直接互相調(diào)用的门躯。

????????而Android系統(tǒng)中,專(zhuān)門(mén)提供了Binder框架來(lái)提供進(jìn)程間通訊和方法調(diào)用的能力酷师。

????????調(diào)用關(guān)系如下圖所示:


2.9?Activity與進(jìn)程創(chuàng)建

??? ????在ActivityManagerService中讶凉,對(duì)每一個(gè)運(yùn)行中的Activity都有一個(gè)ActivityRecord對(duì)象與之對(duì)應(yīng),這個(gè)對(duì)象記錄Activity的詳細(xì)狀態(tài)山孔。

???????ActivityManagerService中的startActivity方法接受Context.startActivity的請(qǐng)求懂讯,該方法代碼如下:

@Override?

public?final?int?startActivity(IApplicationThread?caller,?String?callingPackage,?Intent?intent,?String?resolvedType,?IBinder?resultTo,?String?resultWho,?int?requestCode,?int?startFlags,?ProfilerInfo?profilerInfo,?Bundle?bOptions)?

{?

??? return?startActivityAsUser(caller,?callingPackage,?intent,?resolvedType,?resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId());?

}

??? ????Activity的啟動(dòng)是一個(gè)非常復(fù)雜的過(guò)程。這里我們簡(jiǎn)單介紹一下背景知識(shí):

??????ActivityManagerService中通過(guò)Stack和Task來(lái)管理Activity

??????每一個(gè)Activity都屬于一個(gè)Task台颠,一個(gè)Task可能包含多個(gè)Activity褐望。一個(gè)Stack包含多個(gè)Task

??????ActivityStackSupervisor類(lèi)負(fù)責(zé)管理所有的Stack

??????Activity的啟動(dòng)過(guò)程會(huì)牽涉到:

????????o Intent的解析

????????o Stack,Task的查詢(xún)或創(chuàng)建

????????o Activity進(jìn)程的創(chuàng)建

????????o Activity窗口的創(chuàng)建

????????o Activity的生命周期調(diào)度

????????Activity的管理結(jié)構(gòu)如下圖所示:

????????在Activity啟動(dòng)的最后串前,會(huì)將前一個(gè)Activity pause瘫里,將新啟動(dòng)的Activity resume以便被用戶看到。

??? ????在這個(gè)時(shí)候酪呻,如果發(fā)現(xiàn)新啟動(dòng)的Activity進(jìn)程還沒(méi)有啟動(dòng)减宣,則會(huì)通過(guò)startSpecificActivityLocked將其啟動(dòng)盐须。整個(gè)調(diào)用流程如下:

????· ActivityManagerService.activityPaused =>

????· ActivityStack.activityPausedLocked =>

????· ActivityStack.completePauseLocked =>

????· ActivityStackSupervisor.ensureActivitiesVisibleLocked=>

????· ActivityStack.makeVisibleAndRestartIfNeeded =>

????· ActivityStackSupervisor.startSpecificActivityLocked =>

????· ActivityManagerService.startProcessLocked

????· ActivityStackSupervisor.startSpecificActivityLocked

????????關(guān)鍵代碼如下:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig)?

{

??? // Is this activity's application already running?

??? ProcessRecordapp = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);

???r.task.stack.setLaunchTime(r);


??? if (app != null&& app.thread != null) {

??? ????...

??? }

???mService.startProcessLocked(r.processName, r.info.applicationInfo, true,0, "activity", r.intent.getComponent(), false, false, true);

}

??? ????這里的ProcessRecord app 描述了Activity所在進(jìn)程玩荠。

2.10 Service與進(jìn)程創(chuàng)建

??? ????Service的啟動(dòng)相對(duì)于Activity來(lái)說(shuō)要簡(jiǎn)單一些。在ActivityManagerService中,對(duì)每一個(gè)運(yùn)行中的Service都有一個(gè)ServiceRecord對(duì)象與之對(duì)應(yīng)阶冈,這個(gè)對(duì)象記錄Service的詳細(xì)狀態(tài)闷尿。

???????ActivityManagerService中的startService方法處理Context.startServiceAPI的請(qǐng)求,相關(guān)代碼:

@Override

public ComponentName startService(IApplicationThread caller, Intent service,? String resolvedType, String callingPackage, int userId) throwsTransactionTooLargeException?

{

??? ...

???synchronized(this) {

?????? final intcallingPid = Binder.getCallingPid();

?????? final intcallingUid = Binder.getCallingUid();

?????? final longorigId = Binder.clearCallingIdentity();

?????? ComponentNameres = mServices.startServiceLocked(caller, service, resolvedType, callingPid,callingUid, callingPackage, userId);

??????Binder.restoreCallingIdentity(origId);

?????? return res;

??? }

}

??? ????這段代碼中的mServices對(duì)象是ActiveServices類(lèi)型的女坑,這個(gè)類(lèi)專(zhuān)門(mén)負(fù)責(zé)管理活動(dòng)的Service填具。

??? ????啟動(dòng)Service的調(diào)用流程如下:

????· ActivityManagerService.startService =>

????· ActiveServices.startServiceLocked =>

????· ActiveServices.startServiceInnerLocked =>

????· ActiveServices.bringUpServiceLocked =>

????· ActivityManagerService.startProcessLocked

??? ????ActiveServices.bringUpServiceLocked會(huì)判斷如果Service所在進(jìn)程還沒(méi)有啟動(dòng),則通過(guò)ActivityManagerService.startProcessLocked將其啟動(dòng)匆骗。相關(guān)代碼如下:

// Not running -- get it started, and enqueue this servicerecord

// to be executed when the app comes up.

if (app == null && !permissionsReviewRequired) {

? if((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, "service", r.name, false, isolated, false)) == null) {

????? String msg ="Unable to launch app " + r.appInfo.packageName + "/" + r.appInfo.uid + " for service" + r.intent.getIntent() + ": process is bad";

????? Slog.w(TAG,msg);

?????bringDownServiceLocked(r);

????? return msg;

? }

? if (isolated) {

????? r.isolatedProc= app;

? }

}

??? 這里的mAm 就是ActivityManagerService劳景。


2.11 Provider與進(jìn)程創(chuàng)建

??? ????在ActivityManagerService中,對(duì)每一個(gè)運(yùn)行中的ContentProvider都有一個(gè)ContentProviderRecord對(duì)象與之對(duì)應(yīng)碉就,這個(gè)對(duì)象記錄ContentProvider的詳細(xì)狀態(tài)盟广。

??? ????開(kāi)發(fā)者通過(guò)ContentResolver中的insert, delete, update, query這些API來(lái)使用ContentProvider。在ContentResolver的實(shí)現(xiàn)中瓮钥,無(wú)論使用這里的哪個(gè)接口筋量,ContentResolver都會(huì)先通過(guò)acquireProvider 這個(gè)方法來(lái)獲取到一個(gè)類(lèi)型為IContentProvider的遠(yuǎn)程接口。這個(gè)遠(yuǎn)程接口對(duì)接了ContentProvider的實(shí)現(xiàn)提供方碉熄。

????????同一個(gè)ContentProvider可能同時(shí)被多個(gè)模塊使用桨武,而調(diào)用ContentResolver接口的進(jìn)程只是ContentProvider的一個(gè)客戶端而已,真正的ContentProvider提供方是運(yùn)行自身的進(jìn)程中的锈津,兩個(gè)進(jìn)程的通訊需要通過(guò)Binder的遠(yuǎn)程接口形式來(lái)調(diào)用呀酸。如下圖所示:

??? ????ContentResolver.acquireProvider最終會(huì)調(diào)用到ActivityManagerService.getContentProvider中,該方法代碼如下:

@Override?

public?final?ContentProviderHolder?getContentProvider(IApplicationThread?caller,?String?name,?int?userId,?boolean?stable)?

{?

? ? enforceNotIsolatedCaller("getContentProvider");?

? ? if?(caller?==?null)?{?

? ? ? ? String?msg?="null?IApplicationThread?when?getting?content?provider?"?+?name;?

? ? ? ? Slog.w(TAG,?msg);

? ? ? ? throw?new?SecurityException(msg);

? ?}

??? ????//?The?incoming?user?check?is?now?handled?in?checkContentProviderPermissionLocked()?to?deal?with?cross-user?grant.?

? ??return?getContentProviderImpl(caller,?name,?null,?stable,?userId);?

}

??? ????而在getContentProviderImpl這個(gè)方法中琼梆,會(huì)判斷對(duì)應(yīng)的ContentProvider進(jìn)程有沒(méi)有啟動(dòng)七咧,如果沒(méi)有,則通過(guò)startProcessLocked方法將其啟動(dòng)艾栋。

2.12 Receiver與進(jìn)程創(chuàng)建

??? ????開(kāi)發(fā)者通過(guò)Context.sendBroadcast接口來(lái)發(fā)送廣播扣猫。ActivityManagerService.broadcastIntent方法了對(duì)應(yīng)廣播發(fā)送的處理。

??? ????廣播是一種一對(duì)多的消息形式初坠,廣播接受者的數(shù)量是不確定的。因此發(fā)送廣播本身可能是一個(gè)很耗時(shí)的過(guò)程(因?yàn)橐饌€(gè)通知)重挑。

??? ????在ActivityManagerService內(nèi)部篇梭,是通過(guò)隊(duì)列的形式來(lái)管理廣播的:

????· BroadcastQueue 描述了一個(gè)廣播隊(duì)列

????· BroadcastRecord 描述了一個(gè)廣播事件

??? ????在ActivityManagerService中协怒,如果收到了一個(gè)發(fā)送廣播的請(qǐng)求涝焙,會(huì)先創(chuàng)建一個(gè)BroadcastRecord接著將其放入BroadcastQueue中卑笨。

??? ????然后通知隊(duì)列自己去處理這個(gè)廣播孕暇。然后ActivityManagerService自己就可以繼續(xù)處理其他請(qǐng)求了。

??? ????廣播隊(duì)列本身是在另外一個(gè)線程處理廣播的發(fā)送的赤兴,這樣保證的ActivityManagerService主線程的負(fù)載不會(huì)太重妖滔。

???? ????在BroadcastQueue.processNextBroadcast(boolean fromMsg) 方法中真正實(shí)現(xiàn)了通知廣播事件到接受者的邏輯。在這個(gè)方法桶良,如果發(fā)現(xiàn)接受者(即BrodcastReceiver)還沒(méi)有啟動(dòng)座舍,便會(huì)通過(guò)ActivityManagerService.startProcessLocked方法將其啟動(dòng)。相關(guān)如下所示:

final?void?processNextBroadcast(boolean?fromMsg)?

{?

? ? ...?

? ? //?Hard?case:?need?to?instantiate?the?receiver,?possibly?starting?its?application?process?to?host?it.?


? ? ResolveInfo?info?=?(ResolveInfo)nextReceiver;?

? ? ?????ComponentName?component?=?new?ComponentName(info.activityInfo.applicationInfo.packageName, info.activityInfo.name);?

???? ...?

??????//?Not?running?--?get?it?started,?to?be?executed?when?the?app?comes?up.?

????if?(DEBUG_BROADCAST)

?????????Slog.v(TAG_BROADCAST,"Need?to?start?app?["?+?mQueueName?+?"]?" + targetProcess?+ "?for?broadcast?"?+?r);?

????if?((r.curApp=mService.startProcessLocked(targetProcess,?info.activityInfo.applicationInfo,?true,?r.intent.getFlags()?|?Intent.FLAG_FROM_BACKGROUND,?"broadcast",?r.curComponent,?(r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE)?!=?0,?false,?false))?==?null)?

????{?

? ? ? ? //?Ah,?this?recipient?is?unavailable.??Finish?it?if?necessary,?

? ? ? ? //and?mark?the?broadcast?record?as?ready?for?the?next.? ? ? ? ? ? ? ? ? ? ?????Slog.w(TAG,"Unable?to?launch?app?"?+?info.activityInfo.applicationInfo.packageName + "/" + info.activityInfo.applicationInfo.uid + "?for?broadcast?"?+?r.intent?+?":?process?is?bad");?

? ? ? ? logBroadcastReceiverDiscardLocked(r);

? ? ? ? finishReceiverLocked(r,?r.resultCode,?r.resultData,?r.resultExtras,?r.resultAbort,?false);?

? ? ? ? scheduleBroadcastsLocked();

? ? ? ? r.state?=?BroadcastRecord.IDLE;

? ? ? ??return;?

? ? }?


? ? ?mPendingBroadcast?=?r;?

? ? ?mPendingBroadcastRecvIndex?=?recIdx;?

? }?

}?

??? 至此陨帆,四大組件的啟動(dòng)就已經(jīng)分析完了曲秉。


3 參考鏈接

Android開(kāi)發(fā)之多進(jìn)程詳解

http://blog.csdn.net/feiyang877647044/article/details/51673466


Android 應(yīng)用內(nèi)多進(jìn)程實(shí)現(xiàn) 單APK應(yīng)用多進(jìn)程

http://blog.csdn.net/a78270528/article/details/51143740


ANDROID多進(jìn)程需要注意的一個(gè)地方

http://www.cnblogs.com/John-Chen/p/4364275.html


Android 開(kāi)發(fā)中踩過(guò)的坑之八:多進(jìn)程問(wèn)題

https://my.oschina.net/u/1393188/blog/491568


Android中應(yīng)用多進(jìn)程的整理總結(jié)

http://www.jb51.net/article/104173.htm


Android 后臺(tái)任務(wù)型App多進(jìn)程架構(gòu)演化

http://www.reibang.com/p/4ac1f373e8cd


Android應(yīng)用內(nèi)多進(jìn)程分析和研究

http://blog.csdn.net/goodlixueyong/article/details/49853079


Android開(kāi)啟多進(jìn)程

http://www.2cto.com/kf/201512/455410.html


Android中單APK應(yīng)用多進(jìn)程

http://blog.csdn.net/hudashi/article/details/7858125


Android單應(yīng)用開(kāi)多進(jìn)程與單進(jìn)程跑多應(yīng)用

http://blog.csdn.net/Ragnaro/article/details/51569096


Android應(yīng)用程序進(jìn)程啟動(dòng)過(guò)程的源代碼分析

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


Android應(yīng)用程序在新的進(jìn)程中啟動(dòng)新的Activity的方法和過(guò)程分析

http://shangxun.iteye.com/blog/2124498


(Good)深入理解Dalvik虛擬機(jī)- Android應(yīng)用進(jìn)程啟動(dòng)過(guò)程分析

http://blog.csdn.net/threepigs/article/details/50779056


Android基礎(chǔ) Android應(yīng)用內(nèi)多進(jìn)程分析和研究

http://blog.csdn.net/qq_33326449/article/details/52748710


Android后臺(tái)保活實(shí)踐總結(jié):即時(shí)通訊應(yīng)用無(wú)法根治的“頑疾”

http://www.52im.net/thread-429-1-1.html


Android系統(tǒng)中的進(jìn)程管理:進(jìn)程的創(chuàng)建

http://mobile.51cto.com/android-520139.htm


理解Android進(jìn)程創(chuàng)建流程

http://gityuan.com/2016/03/26/app-process-create/


Android 通過(guò)JNI實(shí)現(xiàn)守護(hù)進(jìn)程

https://blog.csdn.net/yyh352091626/article/details/50542554


android應(yīng)用創(chuàng)建子進(jìn)程的方法探究

https://blog.csdn.net/a332324956/article/details/9114919


UNIX環(huán)境高級(jí)編程(第3版)

深入理解LINUX內(nèi)核(第3版)

Processes and Threads

Android Booting

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疲牵,一起剝皮案震驚了整個(gè)濱河市承二,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纲爸,老刑警劉巖亥鸠,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異识啦,居然都是意外死亡负蚊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)颓哮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)家妆,“玉大人,你說(shuō)我怎么就攤上這事冕茅】玻” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵嵌赠,是天一觀的道長(zhǎng)塑荒。 經(jīng)常有香客問(wèn)我,道長(zhǎng)姜挺,這世上最難降的妖魔是什么齿税? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮炊豪,結(jié)果婚禮上凌箕,老公的妹妹穿的比我還像新娘拧篮。我一直安慰自己,他們只是感情好牵舱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布串绩。 她就那樣靜靜地躺著村生,像睡著了一般穿香。 火紅的嫁衣襯著肌膚如雪梳庆。 梳的紋絲不亂的頭發(fā)上脉幢,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天益咬,我揣著相機(jī)與錄音撒汉,去河邊找鬼湘今。 笑死返劲,一個(gè)胖子當(dāng)著我的面吹牛塞淹,可吹牛的內(nèi)容都是我干的窟蓝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼饱普,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼运挫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起套耕,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谁帕,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后箍铲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體雇卷,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年颠猴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了关划。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡翘瓮,死狀恐怖贮折,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情资盅,我是刑警寧澤调榄,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站呵扛,受9級(jí)特大地震影響每庆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜今穿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一缤灵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦腮出、人聲如沸帖鸦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)作儿。三九已至,卻和暖如春馋劈,著一層夾襖步出監(jiān)牢的瞬間攻锰,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工侣滩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留口注,地道東北人变擒。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓君珠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親娇斑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子策添,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容