Step 5.ZygoteInit.runSelectLoopMode
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
        
  1. publicclassZygoteInit{
  2. ......
  3. /**
  4. *Runsthezygoteprocess'sselectloop.Acceptsnewconnectionsas
  5. *theyhappen,andreadscommandsfromconnectionsonespawn-request's
  6. *worthatatime.
  7. *
  8. *@throwsMethodAndArgsCallerinachildprocesswhenamain()should
  9. *beexecuted.
  10. */
  11. privatestaticvoidrunSelectLoopMode()throwsMethodAndArgsCaller{
  12. ArrayList<FileDescriptor>fds=newArrayList();
  13. ArrayList<ZygoteConnection>peers=newArrayList();
  14. FileDescriptor[]fdArray=newFileDescriptor[4];
  15. fds.add(sServerSocket.getFileDescriptor());
  16. peers.add(null);
  17. intloopCount=GC_LOOP_COUNT;
  18. while(true){
  19. intindex;
  20. /*
  21. *Callgc()beforeweblockinselect().
  22. *It'sworkthathastobedoneanyway,andit'sbetter
  23. *toavoidmakingeverychilddoit.Itwillalso
  24. *madvise()anyfreememoryasaside-effect.
  25. *
  26. *Don'tcalliteverytime,becausewalkingtheentire
  27. *heapisalotofoverheadtofreeafewhundredbytes.
  28. */
  29. if(loopCount<=0){
  30. gc();
  31. loopCount=GC_LOOP_COUNT;
  32. }else{
  33. loopCount--;
  34. }
  35. try{
  36. fdArray=fds.toArray(fdArray);
  37. index=selectReadable(fdArray);
  38. }catch(IOExceptionex){
  39. thrownewRuntimeException("Errorinselect()",ex);
  40. }
  41. if(index<0){
  42. thrownewRuntimeException("Errorinselect()");
  43. }elseif(index==0){
  44. ZygoteConnectionnewPeer=acceptCommandPeer();
  45. peers.add(newPeer);
  46. fds.add(newPeer.getFileDesciptor());
  47. }else{
  48. booleandone;
  49. done=peers.get(index).runOnce();
  50. if(done){
  51. peers.remove(index);
  52. fds.remove(index);
  53. }
  54. }
  55. }
  56. }
  57. ......
  58. }
当Step 4将数据通过Socket接口发送出去后,就会下面这个语句:
        
  1. done=peers.get(index).runOnce();
这里从peers.get(index)得到的是一个ZygoteConnection对象,表示一个Socket连接,因此,接下来就是调用ZygoteConnection.runOnce函数进一步处理了。 Step 6.ZygoteConnection.runOnce 这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
        
  1. classZygoteConnection{
  2. ......
  3. booleanrunOnce()throwsZygoteInit.MethodAndArgsCaller{
  4. Stringargs[];
  5. ArgumentsparsedArgs=null;
  6. FileDescriptor[]descriptors;
  7. try{
  8. args=readArgumentList();
  9. descriptors=mSocket.getAncillaryFileDescriptors();
  10. }catch(IOExceptionex){
  11. ......
  12. returntrue;
  13. }
  14. ......
  15. /**thestderrofthemostrecentrequest,ifavail*/
  16. PrintStreamnewStderr=null;
  17. if(descriptors!=null&&descriptors.length>=3){
  18. newStderr=newPrintStream(
  19. newFileOutputStream(descriptors[2]));
  20. }
  21. intpid;
  22. try{
  23. parsedArgs=newArguments(args);
  24. applyUidSecurityPolicy(parsedArgs,peer);
  25. applyDebuggerSecurityPolicy(parsedArgs);
  26. applyRlimitSecurityPolicy(parsedArgs,peer);
  27. applyCapabilitiesSecurityPolicy(parsedArgs,peer);
  28. int[][]rlimits=null;
  29. if(parsedArgs.rlimits!=null){
  30. rlimits=parsedArgs.rlimits.toArray(intArray2d);
  31. }
  32. pid=Zygote.forkAndSpecialize(parsedArgs.uid,parsedArgs.gid,
  33. parsedArgs.gids,parsedArgs.debugFlags,rlimits);
  34. }catch(IllegalArgumentExceptionex){
  35. ......
  36. }catch(ZygoteSecurityExceptionex){
  37. ......
  38. }
  39. if(pid==0){
  40. //inchild
  41. handleChildProc(parsedArgs,descriptors,newStderr);
  42. //shouldneverhappen
  43. returntrue;
  44. }else{/*pid!=0*/
  45. //inparent...pidof<0meansfailure
  46. returnhandleParentProc(pid,descriptors,parsedArgs);
  47. }
  48. }
  49. ......
  50. }
真正创建进程的地方就是在这里了:
        
  1. pid=Zygote.forkAndSpecialize(parsedArgs.uid,parsedArgs.gid,
  2. parsedArgs.gids,parsedArgs.debugFlags,rlimits);
有Linux开发经验的读者很容易看懂这个函数调用,这个函数会创建一个进程,而且有两个返回值,一个是在当前进程中返回的,一个是在新创建的进程中返回,即在当前进程的子进程中返回,在当前进程中的返回值就是新创建的子进程的pid值,而在子进程中的返回值是0。因为我们只关心创建的新进程的情况,因此,我们沿着子进程的执行路径继续看下去:
        
  1. if(pid==0){
  2. //inchild
  3. handleChildProc(parsedArgs,descriptors,newStderr);
  4. //shouldneverhappen
  5. returntrue;
  6. }else{/*pid!=0*/
  7. ......
  8. }
这里就是调用handleChildProc函数了。 Step 7.ZygoteConnection.handleChildProc
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
        
  1. classZygoteConnection{
  2. ......
  3. privatevoidhandleChildProc(ArgumentsparsedArgs,
  4. FileDescriptor[]descriptors,PrintStreamnewStderr)
  5. throwsZygoteInit.MethodAndArgsCaller{
  6. ......
  7. if(parsedArgs.runtimeInit){
  8. RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
  9. }else{
  10. ......
  11. }
  12. }
  13. ......
  14. }
由于在前面的Step 3中,指定了"--runtime-init"参数,表示要为新创建的进程初始化运行时库,因此,这里的parseArgs.runtimeInit值为true,于是就继续执行RuntimeInit.zygoteInit进一步处理了。 Step 8.RuntimeInit.zygoteInit 这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
  1. publicclassRuntimeInit{
  2. ......
  3. publicstaticfinalvoidzygoteInit(String[]argv)
  4. throwsZygoteInit.MethodAndArgsCaller{
  5. //TODO:Doingthishereworks,butitseemskindofarbitrary.Find
  6. //abetterplace.Thegoalistosetitupforapplications,butnot
  7. //toolslikeam.
  8. System.setOut(newAndroidPrintStream(Log.INFO,"System.out"));
  9. System.setErr(newAndroidPrintStream(Log.WARN,"System.err"));
  10. commonInit();
  11. zygoteInitNative();
  12. intcurArg=0;
  13. for(/*curArg*/;curArg<argv.length;curArg++){
  14. Stringarg=argv[curArg];
  15. if(arg.equals("--")){
  16. curArg++;
  17. break;
  18. }elseif(!arg.startsWith("--")){
  19. break;
  20. }elseif(arg.startsWith("--nice-name=")){
  21. StringniceName=arg.substring(arg.indexOf('=')+1);
  22. Process.setArgV0(niceName);
  23. }
  24. }
  25. if(curArg==argv.length){
  26. Slog.e(TAG,"MissingclassnameargumenttoRuntimeInit!");
  27. //lettheprocessexit
  28. return;
  29. }
  30. //Remainingargumentsarepassedtothestartclass'sstaticmain
  31. StringstartClass=argv[curArg++];
  32. String[]startArgs=newString[argv.length-curArg];
  33. System.arraycopy(argv,curArg,startArgs,0,startArgs.length);
  34. invokeStaticMain(startClass,startArgs);
  35. }
  36. ......
  37. }
这里有两个关键的函数调用,一个是zygoteInitNative函数调用,一个是invokeStaticMain函数调用,前者就是执行Binder驱动程序初始化的相关工作了,正是由于执行了这个工作,才使得进程中的Binder对象能够顺利地进行Binder进程间通信,而后一个函数调用,就是执行进程的入口函数,这里就是执行startClass类的main函数了,而这个startClass即是我们在Step 1中传进来的"android.app.ActivityThread"值,表示要执行android.app.ActivityThread类的main函数。 我们先来看一下zygoteInitNative函数的调用过程,然后再回到RuntimeInit.zygoteInit函数中来,看看它是如何调用android.app.ActivityThread类的main函数的。 step 9.RuntimeInit.zygoteInitNative 这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中: [java] view plain copy
  1. publicclassRuntimeInit{
  2. ......
  3. publicstaticfinalnativevoidzygoteInitNative();
  4. ......
  5. }
这里可以看出,函数zygoteInitNative是一个Native函数,实现在frameworks/base/core/jni/AndroidRuntime.cpp文件中: [cpp] view plain copy
  1. staticvoidcom_android_internal_os_RuntimeInit_zygoteInit(JNIEnv*env,jobjectclazz)
  2. {
  3. gCurRuntime->onZygoteInit();
  4. }
这里它调用了全局变量gCurRuntime的onZygoteInit函数,这个全局变量的定义在frameworks/base/core/jni/AndroidRuntime.cpp文件开头的地方: [cpp] view plain copy
  1. staticAndroidRuntime*gCurRuntime=NULL;
这里可以看出,它的类型为AndroidRuntime,它是在AndroidRuntime类的构造函数中初始化的,AndroidRuntime类的构造函数也是定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中: [cpp] view plain copy
  1. AndroidRuntime::AndroidRuntime()
  2. {
  3. ......
  4. assert(gCurRuntime==NULL);//oneperprocess
  5. gCurRuntime=this;
  6. }
那么这个AndroidRuntime类的构造函数又是什么时候被调用的呢?AndroidRuntime类的声明在frameworks/base/include/android_runtime/AndroidRuntime.h文件中,如果我们打开这个文件会看到,它是一个虚拟类,也就是我们不能直接创建一个AndroidRuntime对象,只能用一个AndroidRuntime类的指针来指向它的某一个子类,这个子类就是AppRuntime了,它定义在frameworks/base/cmds/app_process/app_main.cpp文件中: [cpp] view plain copy
  1. intmain(intargc,constchar*constargv[])
  2. {
  3. ......
  4. AppRuntimeruntime;
  5. ......
  6. }
而AppRuntime类继续了AndroidRuntime类,它也是定义在frameworks/base/cmds/app_process/app_main.cpp文件中: [cpp] view plain copy
  1. classAppRuntime:publicAndroidRuntime
  2. {
  3. ......
  4. };
因此,在前面的com_android_internal_os_RuntimeInit_zygoteInit函数,实际是执行了AppRuntime类的onZygoteInit函数。

更多相关文章

  1. C语言函数以及函数的使用
  2. android:向手机卡上写入文件时总是不成功,解决办法
  3. 在android中使用HttpURLConnection进行文件上传
  4. Android系统进程Zygote启动过程的源代码分析(3)
  5. 转:Android文件操作总结
  6. 【Android的从零单排开发日记】之入门篇(十)——Android应用配置文
  7. [Android Studio] Android Studio如何提示函数用法
  8. 关于android单元测试结合SAX解析xml文件初步分析
  9. Android 进程和线程模型 .

随机推荐

  1. android 自定义 permission 权限
  2. Ogre3D 1.8.1 Android移植
  3. Android EventBus源码分析
  4. Android M5 新特性
  5. [置顶] Android(安卓)Launcher全面剖析
  6. Android(安卓)SettingProvider详解
  7. Android开发——Android手机屏幕适配方案
  8. Android FrameLayout的android:foregroun
  9. 通过判断浏览器的userAgent,用正则来判断
  10. android 入口activity