Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制;这两个特点都是在进程的初始化过程中实现的,本文将详细分析Android应用程序进程创建过程中是如何实现这两个特点的。

Android应用程序框架层创建的应用程序进程的入口函数是ActivityThread.main比较好理解,即进程创建完成之后,Android应用程序框架层就会在这个进程中将ActivityThread类加载进来,然后执行它的main函数,这个main函数就是进程执行消息循环的地方了。Android应用程序框架层创建的应用程序进程天然支持Binder进程间通信机制这个特点应该怎么样理解呢?前面我们在学习Android系统的Binder进程间通信机制时说到,它具有四个组件,分别是驱动程序、守护进程、Client以及Server,其中Server组件在初始化时必须进入一个循环中不断地与Binder驱动程序进行到交互,以便获得Client组件发送的请求,具体可参考Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析一文,但是,当我们在Android应用程序中实现Server组件的时候,我们并没有让进程进入一个循环中去等待Client组件的请求,然而,当Client组件得到这个Server组件的远程接口时,却可以顺利地和Server组件进行进程间通信,这就是因为Android应用程序进程在创建的时候就已经启动了一个线程池来支持Server组件和Binder驱动程序之间的交互了,这样,极大地方便了在Android应用程序中创建Server组件。

在Android应用程序框架层中,是由ActivityManagerService组件负责为Android应用程序创建新的进程的,它本来也是运行在一个独立的进程之中,不过这个进程是在系统启动的过程中创建的。ActivityManagerService组件一般会在什么情况下会为应用程序创建一个新的进程呢?当系统决定要在一个新的进程中启动一个Activity或者Service时,它就会创建一个新的进程了,然后在这个新的进程中启动这个Activity或者Service,具体可以参考Android系统在新进程中启动自定义服务过程(startService)的原理分析、Android应用程序启动过程源代码分析和Android应用程序在新的进程中启动新的Activity的方法和过程分析这三篇文章。

ActivityManagerService启动新的进程是从其成员函数startProcessLocked开始的,在深入分析这个过程之前,我们先来看一下进程创建过程的序列图,然后再详细分析每一个步骤。

Step 1. ActivityManagerService.startProcessLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

        
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalvoidstartProcessLocked(ProcessRecordapp,
  5. StringhostingType,StringhostingNameStr){
  6. ......
  7. try{
  8. intuid=app.info.uid;
  9. int[]gids=null;
  10. try{
  11. gids=mContext.getPackageManager().getPackageGids(
  12. app.info.packageName);
  13. }catch(PackageManager.NameNotFoundExceptione){
  14. ......
  15. }
  16. ......
  17. intdebugFlags=0;
  18. ......
  19. intpid=Process.start("android.app.ActivityThread",
  20. mSimpleProcessManagement?app.processName:null,uid,uid,
  21. gids,debugFlags,null);
  22. ......
  23. }catch(RuntimeExceptione){
  24. ......
  25. }
  26. }
  27. ......
  28. }

它调用了Process.start函数开始为应用程序创建新的进程,注意,它传入一个第一个参数为"android.app.ActivityThread",这就是进程初始化时要加载的Java类了,把这个类加载到进程之后,就会把它里面的静态成员函数main作为进程的入口点,后面我们会看到。

Step 2. Process.start

这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:

        
  1. publicclassProcess{
  2. ......
  3. publicstaticfinalintstart(finalStringprocessClass,
  4. finalStringniceName,
  5. intuid,intgid,int[]gids,
  6. intdebugFlags,
  7. String[]zygoteArgs)
  8. {
  9. if(supportsProcesses()){
  10. try{
  11. returnstartViaZygote(processClass,niceName,uid,gid,gids,
  12. debugFlags,zygoteArgs);
  13. }catch(ZygoteStartFailedExex){
  14. ......
  15. }
  16. }else{
  17. ......
  18. return0;
  19. }
  20. }
  21. ......
  22. }

这里的supportsProcesses函数返回值为true,它是一个Native函数,实现在frameworks/base/core/jni/android_util_Process.cpp文件中:

        
  1. jbooleanandroid_os_Process_supportsProcesses(JNIEnv*env,jobjectclazz)
  2. {
  3. returnProcessState::self()->supportsProcesses();
  4. }

ProcessState::supportsProcesses函数定义在frameworks/base/libs/binder/ProcessState.cpp文件中:

        
  1. boolProcessState::supportsProcesses()const
  2. {
  3. returnmDriverFD>=0;
  4. }

这里的mDriverFD是设备文件/dev/binder的打开描述符,如果成功打开了这个设备文件,那么它的值就会大于等于0,因此,它的返回值为true。

回到Process.start函数中,它调用startViaZygote函数进一步操作。

Step 3.Process.startViaZygote

这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:

        
  1. publicclassProcess{
  2. ......
  3. privatestaticintstartViaZygote(finalStringprocessClass,
  4. finalStringniceName,
  5. finalintuid,finalintgid,
  6. finalint[]gids,
  7. intdebugFlags,
  8. String[]extraArgs)
  9. throwsZygoteStartFailedEx{
  10. intpid;
  11. synchronized(Process.class){
  12. ArrayList<String>argsForZygote=newArrayList<String>();
  13. //--runtime-init,--setuid=,--setgid=,
  14. //and--setgroups=mustgofirst
  15. argsForZygote.add("--runtime-init");
  16. argsForZygote.add("--setuid="+uid);
  17. argsForZygote.add("--setgid="+gid);
  18. if((debugFlags&Zygote.DEBUG_ENABLE_SAFEMODE)!=0){
  19. argsForZygote.add("--enable-safemode");
  20. }
  21. if((debugFlags&Zygote.DEBUG_ENABLE_DEBUGGER)!=0){
  22. argsForZygote.add("--enable-debugger");
  23. }
  24. if((debugFlags&Zygote.DEBUG_ENABLE_CHECKJNI)!=0){
  25. argsForZygote.add("--enable-checkjni");
  26. }
  27. if((debugFlags&Zygote.DEBUG_ENABLE_ASSERT)!=0){
  28. argsForZygote.add("--enable-assert");
  29. }
  30. //TODOoptionallyenabledebuger
  31. //argsForZygote.add("--enable-debugger");
  32. //--setgroupsisacomma-separatedlist
  33. if(gids!=null&&gids.length>0){
  34. StringBuildersb=newStringBuilder();
  35. sb.append("--setgroups=");
  36. intsz=gids.length;
  37. for(inti=0;i<sz;i++){
  38. if(i!=0){
  39. sb.append(',');
  40. }
  41. sb.append(gids[i]);
  42. }
  43. argsForZygote.add(sb.toString());
  44. }
  45. if(niceName!=null){
  46. argsForZygote.add("--nice-name="+niceName);
  47. }
  48. argsForZygote.add(processClass);
  49. if(extraArgs!=null){
  50. for(Stringarg:extraArgs){
  51. argsForZygote.add(arg);
  52. }
  53. }
  54. pid=zygoteSendArgsAndGetPid(argsForZygote);
  55. }
  56. }
  57. ......
  58. }

这个函数将创建进程的参数放到argsForZygote列表中去,如参数"--runtime-init"表示要为新创建的进程初始化运行时库,然后调用zygoteSendAndGetPid函数进一步操作。

Step 4. Process.zygoteSendAndGetPid

这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:

        
  1. publicclassProcess{
  2. ......
  3. privatestaticintzygoteSendArgsAndGetPid(ArrayList<String>args)
  4. throwsZygoteStartFailedEx{
  5. intpid;
  6. openZygoteSocketIfNeeded();
  7. try{
  8. /**
  9. *Seecom.android.internal.os.ZygoteInit.readArgumentList()
  10. *Presentlythewireformattothezygoteprocessis:
  11. *a)acountofarguments(argc,inessence)
  12. *b)anumberofnewline-separatedargumentstringsequaltocount
  13. *
  14. *Afterthezygoteprocessreadstheseitwillwritethepidof
  15. *thechildor-1onfailure.
  16. */
  17. sZygoteWriter.write(Integer.toString(args.size()));
  18. sZygoteWriter.newLine();
  19. intsz=args.size();
  20. for(inti=0;i<sz;i++){
  21. Stringarg=args.get(i);
  22. if(arg.indexOf('\n')>=0){
  23. thrownewZygoteStartFailedEx(
  24. "embeddednewlinesnotallowed");
  25. }
  26. sZygoteWriter.write(arg);
  27. sZygoteWriter.newLine();
  28. }
  29. sZygoteWriter.flush();
  30. //Shouldtherebeatimeoutonthis?
  31. pid=sZygoteInputStream.readInt();
  32. if(pid<0){
  33. thrownewZygoteStartFailedEx("fork()failed");
  34. }
  35. }catch(IOExceptionex){
  36. ......
  37. }
  38. returnpid;
  39. }
  40. ......
  41. }

这里的sZygoteWriter是一个Socket写入流,是由openZygoteSocketIfNeeded函数打开的:

        
  1. publicclassProcess{
  2. ......
  3. /**
  4. *TriestoopensockettoZygoteprocessifnotalreadyopen.If
  5. *alreadyopen,doesnothing.Mayblockandretry.
  6. */
  7. privatestaticvoidopenZygoteSocketIfNeeded()
  8. throwsZygoteStartFailedEx{
  9. intretryCount;
  10. if(sPreviousZygoteOpenFailed){
  11. /*
  12. *Ifwe'vefailedbefore,expectthatwe'llfailagainand
  13. *don'tpauseforretries.
  14. */
  15. retryCount=0;
  16. }else{
  17. retryCount=10;
  18. }
  19. /*
  20. *Seebug#811181:Sometimesruntimecanmakeitupbeforezygote.
  21. *Really,we'dliketodosomethingbettertoavoidthiscondition,
  22. *butfornowjustwaitabit...
  23. */
  24. for(intretry=0
  25. ;(sZygoteSocket==null)&&(retry<(retryCount+1))
  26. ;retry++){
  27. if(retry>0){
  28. try{
  29. Log.i("Zygote","Zygotenotupyet,sleeping...");
  30. Thread.sleep(ZYGOTE_RETRY_MILLIS);
  31. }catch(InterruptedExceptionex){
  32. //shouldneverhappen
  33. }
  34. }
  35. try{
  36. sZygoteSocket=newLocalSocket();
  37. sZygoteSocket.connect(newLocalSocketAddress(ZYGOTE_SOCKET,
  38. LocalSocketAddress.Namespace.RESERVED));
  39. sZygoteInputStream
  40. =newDataInputStream(sZygoteSocket.getInputStream());
  41. sZygoteWriter=
  42. newBufferedWriter(
  43. newOutputStreamWriter(
  44. sZygoteSocket.getOutputStream()),
  45. 256);
  46. Log.i("Zygote","Process:zygotesocketopened");
  47. sPreviousZygoteOpenFailed=false;
  48. break;
  49. }catch(IOExceptionex){
  50. ......
  51. }
  52. }
  53. ......
  54. }
  55. ......
  56. }

这个Socket由frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的ZygoteInit类在runSelectLoopMode函数侦听的。

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. 【android内核分析-启动】Android(安卓)启动过程详解
  4. Android(安卓)AIDL 跨进程服务 Proxy/Stub
  5. Android(安卓)第一课——Android架构
  6. Android应用程序注册广播接收器(registerReceiver)的过程分析
  7. Android(安卓)操作系统的内存回收机制
  8. Android应用程序注册广播接收器(registerReceiver)的过程分析
  9. Android(安卓)无线接口层RIL(Radio Layer Interface)

随机推荐

  1. java中匹配字符串中的中文字符(含中文标
  2. Java nio 学习笔记(一) Buffer(缓冲区)与Chan
  3. 如何知道Object是否为String类型对象?
  4. Java实现图像对比类
  5. Eclipse Juno 4.2的Swing插件[重复]
  6. 关于JAVA类加载大家发表一下见解吧
  7. Java标准标签库学习小结
  8. Javascript实现页面加载完成后自动刷新一
  9. tomcat启动报错问题!求帮忙看看
  10. javascript小例子--实现邮箱验证的功能