《Android应用程序进程启动过程的源代码分析.docx》由会员分享,可在线阅读,更多相关《Android应用程序进程启动过程的源代码分析.docx(26页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、 Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制;这两个特点都是在进程的初始化过程中实现的,本文将详细分析Android应用程序进程创建过程中是如何实现这两个特点的。 Android应用程序框架层创建的应用程序进程的入口函数是ActivityThread.main比较好理解,即进程创建完成之后,Android应用程序框架层就会在这个进程中将ActivityThread类加载进来,然后执行它的main函数,这个main函数就是进程执行消息循环的地方了。Android应用程序框架层创
2、建的应用程序进程天然支持Binder进程间通信机制这个特点应该怎么样理解呢?前面我们在学习Android系统的Binder进程间通信机制时说到,它具有四个组件,分别是驱动程序、守护进程、Client以及Server,其中Server组件在初始化时必须进入一个循环中不断地与Binder驱动程序进行到交互,以便获得Client组件发送的请求,具体可参考Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析一文,但是,当我们在Android应用程序中实现Server组件的时候,我们并没有让进程进入一个循环中去等待Client组件的请求,然而,当Client组件得到这
3、个Server组件的远程接口时,却可以顺利地和Server组件进行进程间通信,这就是因为Android应用程序进程在创建的时候就已经启动了一个线程池来支持Server组件和Binder驱动程序之间的交互了,这样,极大地方便了在Android应用程序中创建Server组件。 在Android应用程序框架层中,是由ActivityManagerService组件负责为Android应用程序创建新的进程的,它本来也是运行在一个独立的进程之中,不过这个进程是在系统启动的过程中创建的。ActivityManagerService组件一般会在什么情况下会为应用程序创建一个新的进程呢?当系统决定要在一个新的
4、进程中启动一个Activity或者Service时,它就会创建一个新的进程了,然后在这个新的进程中启动这个Activity或者Service,具体可以参考Android系统在新进程中启动自定义服务过程(startService)的原理分析、Android应用程序启动过程源代码分析和Android应用程序在新的进程中启动新的Activity的方法和过程分析这三篇文章。 ActivityManagerService启动新的进程是从其成员函数startProcessLocked开始的,在深入分析这个过程之前,我们先来看一下进程创建过程的序列图,然后再详细分析每一个步骤。 点击查看大图 Step 1.
5、 ActivityManagerService.startProcessLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:view plain1. publicfinalclassActivityManagerServiceextendsActivityManagerNative2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback3. 4. .5. 6. privatefinalv
6、oidstartProcessLocked(ProcessRecordapp,7. StringhostingType,StringhostingNameStr)8. 9. .10. 11. try12. intuid=app.info.uid;13. intgids=null;14. try15. gids=mContext.getPackageManager().getPackageGids(16. app.info.packageName);17. catch(PackageManager.NameNotFoundExceptione)18. .19. 20. 21. .22. 23.
7、intdebugFlags=0;24. 25. .26. 27. intpid=Process.start(android.app.ActivityThread,28. mSimpleProcessManagement?app.processName:null,uid,uid,29. gids,debugFlags,null);30. 31. .32. 33. catch(RuntimeExceptione)34. 35. .36. 37. 38. 39. 40. .41. 42. 它调用了Process.start函数开始为应用程序创建新的进程,注意,它传入一个第一个参数为android.a
8、pp.ActivityThread,这就是进程初始化时要加载的Java类了,把这个类加载到进程之后,就会把它里面的静态成员函数main作为进程的入口点,后面我们会看到。 Step 2. Process.start 这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:view plain1. publicclassProcess2. .3. 4. publicstaticfinalintstart(finalStringprocessClass,5. finalStringniceName,6. intuid,intgid,in
9、tgids,7. intdebugFlags,8. StringzygoteArgs)9. 10. if(supportsProcesses()11. try12. returnstartViaZygote(processClass,niceName,uid,gid,gids,13. debugFlags,zygoteArgs);14. catch(ZygoteStartFailedExex)15. .16. 17. else18. .19. 20. return0;21. 22. 23. 24. .25. 这里的supportsProcesses函数返回值为true,它是一个Native函数
10、,实现在frameworks/base/core/jni/android_util_Process.cpp文件中:view plain1. jbooleanandroid_os_Process_supportsProcesses(JNIEnv*env,jobjectclazz)2. 3. returnProcessState:self()-supportsProcesses();4. ProcessState:supportsProcesses函数定义在frameworks/base/libs/binder/ProcessState.cpp文件中:view plain1. boolProces
11、sState:supportsProcesses()const2. 3. returnmDriverFD=0;4. 这里的mDriverFD是设备文件/dev/binder的打开描述符,如果成功打开了这个设备文件,那么它的值就会大于等于0,因此,它的返回值为true。 回到Process.start函数中,它调用startViaZygote函数进一步操作。 Step 3.Process.startViaZygote 这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:view plain1. publicclassProces
12、s2. .3. 4. privatestaticintstartViaZygote(finalStringprocessClass,5. finalStringniceName,6. finalintuid,finalintgid,7. finalintgids,8. intdebugFlags,9. StringextraArgs)10. throwsZygoteStartFailedEx11. intpid;12. 13. synchronized(Process.class)14. ArrayListargsForZygote=newArrayList();15. 16. /-runti
13、me-init,-setuid=,-setgid=,17. /and-setgroups=mustgofirst18. argsForZygote.add(-runtime-init);19. argsForZygote.add(-setuid=+uid);20. argsForZygote.add(-setgid=+gid);21. if(debugFlags&Zygote.DEBUG_ENABLE_SAFEMODE)!=0)22. argsForZygote.add(-enable-safemode);23. 24. if(debugFlags&Zygote.DEBUG_ENABLE_DE
14、BUGGER)!=0)25. argsForZygote.add(-enable-debugger);26. 27. if(debugFlags&Zygote.DEBUG_ENABLE_CHECKJNI)!=0)28. argsForZygote.add(-enable-checkjni);29. 30. if(debugFlags&Zygote.DEBUG_ENABLE_ASSERT)!=0)31. argsForZygote.add(-enable-assert);32. 33. 34. /TODOoptionallyenabledebuger35. /argsForZygote.add(
15、-enable-debugger);36. 37. /-setgroupsisacomma-separatedlist38. if(gids!=null&gids.length0)39. StringBuildersb=newStringBuilder();40. sb.append(-setgroups=);41. 42. intsz=gids.length;43. for(inti=0;isz;i+)44. if(i!=0)45. sb.append(,);46. 47. sb.append(gidsi);48. 49. 50. argsForZygote.add(sb.toString(
16、);51. 52. 53. if(niceName!=null)54. argsForZygote.add(-nice-name=+niceName);55. 56. 57. argsForZygote.add(processClass);58. 59. if(extraArgs!=null)60. for(Stringarg:extraArgs)61. argsForZygote.add(arg);62. 63. 64. 65. pid=zygoteSendArgsAndGetPid(argsForZygote);66. 67. 68. 69. .70. 这个函数将创建进程的参数放到args
17、ForZygote列表中去,如参数-runtime-init表示要为新创建的进程初始化运行时库,然后调用zygoteSendAndGetPid函数进一步操作。 Step 4. Process.zygoteSendAndGetPid 这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:view plain1. publicclassProcess2. .3. 4. privatestaticintzygoteSendArgsAndGetPid(ArrayListargs)5. throwsZygoteStartFailedEx6
18、. intpid;7. 8. openZygoteSocketIfNeeded();9. 10. try11. /*12. *Seecom.android.internal.os.ZygoteInit.readArgumentList()13. *Presentlythewireformattothezygoteprocessis:14. *a)acountofarguments(argc,inessence)15. *b)anumberofnewline-separatedargumentstringsequaltocount16. *17. *Afterthezygoteprocessre
19、adstheseitwillwritethepidof18. *thechildor-1onfailure.19. */20. 21. sZygoteWriter.write(Integer.toString(args.size();22. sZygoteWriter.newLine();23. 24. intsz=args.size();25. for(inti=0;i=0)28. thrownewZygoteStartFailedEx(29. embeddednewlinesnotallowed);30. 31. sZygoteWriter.write(arg);32. sZygoteWr
20、iter.newLine();33. 34. 35. sZygoteWriter.flush();36. 37. /Shouldtherebeatimeoutonthis?38. pid=sZygoteInputStream.readInt();39. 40. if(pid0)41. thrownewZygoteStartFailedEx(fork()failed);42. 43. catch(IOExceptionex)44. .45. 46. 47. returnpid;48. 49. 50. .51. 这里的sZygoteWriter是一个Socket写入流,是由openZygoteSo
21、cketIfNeeded函数打开的:view plain1. publicclassProcess2. .3. 4. /*5. *TriestoopensockettoZygoteprocessifnotalreadyopen.If6. *alreadyopen,doesnothing.Mayblockandretry.7. */8. privatestaticvoidopenZygoteSocketIfNeeded()9. throwsZygoteStartFailedEx10. 11. intretryCount;12. 13. if(sPreviousZygoteOpenFailed)1
22、4. /*15. *Ifwevefailedbefore,expectthatwellfailagainand16. *dontpauseforretries.17. */18. retryCount=0;19. else20. retryCount=10;21. 22. 23. /*24. *Seebug#811181:Sometimesruntimecanmakeitupbeforezygote.25. *Really,wedliketodosomethingbettertoavoidthiscondition,26. *butfornowjustwaitabit.27. */28. fo
23、r(intretry=029. ;(sZygoteSocket=null)&(retry0)33. try34. Log.i(Zygote,Zygotenotupyet,sleeping.);35. Thread.sleep(ZYGOTE_RETRY_MILLIS);36. catch(InterruptedExceptionex)37. /shouldneverhappen38. 39. 40. 41. try42. sZygoteSocket=newLocalSocket();43. sZygoteSocket.connect(newLocalSocketAddress(ZYGOTE_SO
24、CKET,44. LocalSocketAddress.Namespace.RESERVED);45. 46. sZygoteInputStream47. =newDataInputStream(sZygoteSocket.getInputStream();48. 49. sZygoteWriter=50. newBufferedWriter(51. newOutputStreamWriter(52. sZygoteSocket.getOutputStream(),53. 256);54. 55. Log.i(Zygote,Process:zygotesocketopened);56. 57.
25、 sPreviousZygoteOpenFailed=false;58. break;59. catch(IOExceptionex)60. .61. 62. 63. 64. .65. 66. 67. .68. 这个Socket由frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的ZygoteInit类在runSelectLoopMode函数侦听的。 Step 5.ZygoteInit.runSelectLoopMode 这个函数定义在frameworks/base/core/java/com/android
26、/internal/os/ZygoteInit.java文件中:view plain1. publicclassZygoteInit2. .3. 4. /*5. *Runsthezygoteprocesssselectloop.Acceptsnewconnectionsas6. *theyhappen,andreadscommandsfromconnectionsonespawn-requests7. *worthatatime.8. *9. *throwsMethodAndArgsCallerinachildprocesswhenamain()should10. *beexecuted.11
27、. */12. privatestaticvoidrunSelectLoopMode()throwsMethodAndArgsCaller13. ArrayListfds=newArrayList();14. ArrayListpeers=newArrayList();15. FileDescriptorfdArray=newFileDescriptor4;16. 17. fds.add(sServerSocket.getFileDescriptor();18. peers.add(null);19. 20. intloopCount=GC_LOOP_COUNT;21. while(true)
28、22. intindex;23. /*24. *Callgc()beforeweblockinselect().25. *Itsworkthathastobedoneanyway,anditsbetter26. *toavoidmakingeverychilddoit.Itwillalso27. *madvise()anyfreememoryasaside-effect.28. *29. *Dontcalliteverytime,becausewalkingtheentire30. *heapisalotofoverheadtofreeafewhundredbytes.31. */32. if
29、(loopCount=0)33. gc();34. loopCount=GC_LOOP_COUNT;35. else36. loopCount-;37. 38. 39. 40. try41. fdArray=fds.toArray(fdArray);42. index=selectReadable(fdArray);43. catch(IOExceptionex)44. thrownewRuntimeException(Errorinselect(),ex);45. 46. 47. if(index0)48. thrownewRuntimeException(Errorinselect();4
30、9. elseif(index=0)50. ZygoteConnectionnewPeer=acceptCommandPeer();51. peers.add(newPeer);52. fds.add(newPeer.getFileDesciptor();53. else54. booleandone;55. done=peers.get(index).runOnce();56. 57. if(done)58. peers.remove(index);59. fds.remove(index);60. 61. 62. 63. 64. 65. .66. 当Step 4将数据通过Socket接口发送出去后,就会下面这个语句:view plain1. done=peers.get(index).runOnce(); 这里从peers.get(index)得到的是一个ZygoteConnection对象,表示一个Socket连接,因此,接下来就是调用ZygoteConnection.runOnce函数