Android源码解析四大组件系列(三)---Activity启动过程之ActivityThread是如何运行起来的

这篇文章,深入源码,分析Launcher进程向SystemServer进程发起startActivity请求,SystemServer进程在向zygote进程发起请求,最后孵化出应用进程(我们的APP进程)的这一过程,为什么要分析这个呢,在APP只有一个进程的情况下,通常以冷启动的方式打开APP的一个Activity与热启动的方式打开一个Activity的流程是不一样的,我认为Activity的启动可以分两步,第一阶段是进程启动阶段,通过Zygote启动进程,第二阶段是Activity启动阶段,在新的进程里,启动Activity,这篇博客就是要弄清楚,我们简单的点击一下桌面图标,第一个Activity是怎么被启动的。

一、Zygote进程fork APP进程

Zygote进程,是由init进程fork生成的,init启动zygote时主要是调用app_main.cpp的main函数中的AppRuntime的start来启动zygote进程。我们直接从ZygoteInit的入口开始讲,太深入的不讨论。

 public static void main(String argv[]) {
        try {
            //1、开启DDMS功能
            RuntimeInit.enableDdms();
            SamplingProfilerIntegration.start();

            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)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

           //2、Zygote进程通信的方式不是Binder,而是Socket,所以这里创建一个Server端的Socket
            registerZygoteSocket(socketName);
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,

                SystemClock.uptimeMillis());
              //3、预加载类和资源,内部调用了preloadClasses()和preloadResourse()的调用
            preload();

             ............ 

            if (startSystemServer) {
               //4、启动system_server进程,这是受精卵进程的第一次分裂
                startSystemServer(abiList, socketName);
            }

           //5、Server端的Socket创建好了,等待着接收ActivityManagerService的请求
            runSelectLoop(abiList);

            closeServerSocket();

        } catch (MethodAndArgsCaller caller) {
            caller.run();//6、important,通过捕获异常的方式,执行SystemServer的main方法
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

ZygoteInit的main方法大概就做了上面六件事情,一,开启DDMS功能;二,创建一个Server端的Socket,作用是当Zygote进程将SystemServer进程启动后,就会在这个Socket上来等待ActivityManagerService请求,即请求创建我们自己APP应用程序进程;三,预加载类和资源,包括颜色啊,R文件,drawable等;四,启动system_server进程,这是上层framework的运行载体,ActivityManagerService就是运行在这个进程里面的;五,开启一个循环,等待着接收ActivityManagerService的请求,随时待命,当接收到创建新进程的请求时立即唤醒并执行相应工作;六,通过捕获异常的方式,执行SystemServer的main方法。

具体的源码,就不看了,ZygoteInit总共源码才七百多行,我们需要知道的是,ZygoteInit进程启动后,会注册一个Socket,在runSelectLoop方法中开启一个while死循环等待ActivityManagerService创建新进程的请求,其次,ZygoteInit启动了SystemServer进程,执行SystemServer的main方法。就这么多就足够了,具体可以结合源码研究

二、Zygote进程怎么通知ActivityThread的main方法执行

ZygoteInit启动了SystemServer进程,之后AMS就会注册,关于AMS服务注册以及启动,在上一篇博文中已经讲解过了戳我,AMS是在SystemServer中的startBootstrapServices方法中启动的,紧接着,在startBootstrapServices方法之后,就调用 startOtherServices(),在这个方法中,调用了 mActivityManagerService.systemReady。

里面执行了各种其他服务的systemReady方法

  public void systemReady(final Runnable goingCallback) {
        synchronized(this) {
            if (mSystemReady) {
             ............ 
                   省略了其他非相关代码
                 startHomeActivityLocked(currentUserId, "systemReady");
              ............ 
             }
        }   
    }

startHomeActivityLocked调用之后,会调用如下一些重载方法,考虑篇幅不分析了,比较复杂。

    ActivityStackSupervisor
           startHomeActivity(Intent intent, ActivityInfo aInfo, String reason)
           startActivityLocked(IApplicationThread caller,
                Intent intent, String resolvedType, ActivityInfo aInfo,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                IBinder resultTo, String resultWho, int requestCode,
                int callingPid, int callingUid, String callingPackage,
                int realCallingPid, int realCallingUid, int startFlags, Bundle options,
                boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
                ActivityContainer container, TaskRecord inTask)

           startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
                boolean doResume, Bundle options, TaskRecord inTask)

           resumeTopActivitiesLocked()
                resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
                Bundle targetOptions)

    ActivityStatck
             resumeTopActivityLocked(ActivityRecord prev)
             resumeTopActivityLocked(ActivityRecord prev, Bundle options) 
             resumeTopActivityLocked(ActivityRecord prev, Bundle options) 
             resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) 

    ActivityStackSupervisor
            startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) 


    ActivityManagerService
            startProcessLocked(String processName,
                ApplicationInfo info, boolean knownToBeDead, int intentFlags,
                String hostingType, ComponentName hostingName, boolean allowWhileBooting,
                boolean isolated, boolean keepIfLarge)
            startProcessLocked(ProcessRecord app, String hostingType,
                String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)

最后会调用startProcessLocked方法,具体实现如下。

 private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        ......

            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.

            boolean isActivityProcess = (entryPoint == null);

            if (entryPoint == null) entryPoint = "android.app.ActivityThread";


            checkTime(startTime, "startProcess: asking zygote to start proc");

            //这里很重要,
            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);

        ......    

    }

调用 Process.start创建进程,并在该进程中运行android.app.ActivityThread的main方法,
Process路径sdk\sources\android-23\android\os\Process.java,继续分析 Process.start。

 public static final ProcessStartResult 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) {
           ......    
        }
    }

startViaZygote中会调用openZygoteSocketIfNeeded。


   private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            try {
              //连接到Zygote的Soceket
                primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
            }
        }

        if (primaryZygoteState.matches(abi)) {
            return primaryZygoteState;
        }

        // 如果没有连接成功,尝试第二次连接
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            try {
            secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
            }
        }

        if (secondaryZygoteState.matches(abi)) {
            return secondaryZygoteState;
        }

        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    }

 public static ZygoteState connect(String socketAddress) throws IOException {
            DataInputStream zygoteInputStream = null;
            BufferedWriter zygoteWriter = null;
           //创建socket,去连接zygote的Socket
            final LocalSocket zygoteSocket = new LocalSocket();

            try {
                zygoteSocket.connect(new LocalSocketAddress(socketAddress,
                        LocalSocketAddress.Namespace.RESERVED));

                zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());

                zygoteWriter = new BufferedWriter(new OutputStreamWriter(
                        zygoteSocket.getOutputStream()), 256);
            } catch (IOException ex) {
             .......
            }
.......

            return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
                    Arrays.asList(abiListString.split(",")));
        }

当上面的socket去connect的时候,ZygoteInit里面的Socket就会响应 ,到此我们绕了一大圈,再次从SystemServer进程回到Zygote进程中。所以SystemServer进程和Zygote进程是靠Socket通信的,AMS发送了连接请求到Zygote的Socket,在第一小节说过,,在runSelectLoop方法中开启一个while死循环等待ActivityManagerService创建新进程的请求,我们需要去看runSelectLoop。

 private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    //会走这里,处理AMS创建新进程请求
                    boolean done = peers.get(i).runOnce();
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

调用runOnce处理

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
        ...

        try {
            if (pid == 0) {
                // in child
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                //处理子进程
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

                // should never get here, the child is expected to either
                // throw ZygoteInit.MethodAndArgsCaller or exec().
                return true;
            } else {
                // in parent...pid of < 0 means failure
                //父进程出错处理
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                //处理父进程,也就是Zygote进程
                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }
    }

在handleChildProc中会调用到zygoteInit

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
        //重定向标准IO操作到Android日志系统
        redirectLogStreams();
        //一些配置,比如设置HTTP User-Agent
        commonInit();
        //开启Binder通信
        nativeZygoteInit();

        applicationInit(targetSdkVersion, argv, classLoader);
    }
  private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;

        try {
     //1、这里会创建ActivityThrad对象
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
     //2、获取main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        ......
      //3、抛出异常,
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }
ZygoteInit.main中会捕获这个MethodAndArgsCaller异常,调用了main方法。

 ```
   try {}catch (MethodAndArgsCaller caller) { caller.run();  }
  public void run() {
            try {
                //Activity的main方法执行起来
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }

OK, 到此Zygote孵化应用进程后,主线程终于跑起来了。下一篇讲解ActivityThread启动之后,AMS怎么与之进程通信。

参考:http://blog.csdn.net/qq_23547831/article/details/51224992

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值