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