Android应用程序进程启动过程的源代码分析.docx

上传人:asd****56 文档编号:70335309 上传时间:2023-01-19 格式:DOCX 页数:26 大小:131.20KB
返回 下载 相关 举报
Android应用程序进程启动过程的源代码分析.docx_第1页
第1页 / 共26页
Android应用程序进程启动过程的源代码分析.docx_第2页
第2页 / 共26页
点击查看更多>>
资源描述

《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函数

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com