Activity的启动流程(二)

 

在前面的介绍的Activity启动流程中,跳过了进程的构建和ActivityThread开始运行的部分,本文就详细展开该过程。

 

ActivityManagerService启动一个新的进程作为容器

ActivityManagerService.java

  private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) {

      // Process里面通知Zygote服务,Zygote真正产生新的进程(准确说是复制一个)

      int pid = Process.start("android.app.ActivityThread",
                    mSimpleProcessManagement ? app.processName : null, uid, uid,

  }

 

Process.java

public static final int start(final String processClass,  final String niceName,
                                  int uid, int gid, int[] gids,  int debugFlags,  String[] zygoteArgs)
{

      // 现在的android系统都是支持多进程的,所以应用程序都在单独的进程控件中运行
      if (supportsProcesses()) {

          // 由Zygote服务启动新的进程
          return startViaZygote(processClass, niceName, uid, gid, gids,
                        debugFlags, zygoteArgs);
        } else {
            // 单进程模式,所有的Android 应用都共享同一个进程 空间
            Runnable runnable = new Runnable() {

                        public void run() {
                            Process.invokeStaticMain(processClass);
                        }
            };
           
            // Thread constructors must not be called with null names (see spec).
            if (niceName != null) {
                new Thread(runnable, niceName).start();
            } else {
                new Thread(runnable).start();
            }
           
            return 0;
        }
    }
   
private static int startViaZygote(final String processClass,  final String niceName,
                final int uid, final int gid,  final int[] gids, int debugFlags, String[] extraArgs)

{

     synchronized(Process.class) {
           ArrayList<String> argsForZygote = new ArrayList<String>();

           // --runtime-init
           argsForZygote.add("--runtime-init");

           // 设置进程的uid和gid

           argsForZygote.add("--setuid=" + uid);
           argsForZygote.add("--setgid=" + gid);

 

           // --setgroups is a comma-separated list
           if (gids != null && gids.length > 0) {
                StringBuilder sb = new StringBuilder();
                sb.append("--setgroups=");

                int sz = gids.length;
                for (int i = 0; i < sz; i++) {
                    if (i != 0) {
                        sb.append(',');
                    }
                    sb.append(gids[i]);
                }

                argsForZygote.add(sb.toString());
            }

            if (niceName != null) {
                argsForZygote.add("--nice-name=" + niceName);
            }

            argsForZygote.add(processClass);

            // 通过socket将参数列表传给Zygote并返回新生的进程ID

            pid = zygoteSendArgsAndGetPid(argsForZygote);

      }
}

 

 

Zygote服务监听本地/dev/socket设备

 

private static void runSelectLoopMode() throws MethodAndArgsCaller {
     while (true) {
          fdArray = fds.toArray(fdArray);
          index = selectReadable(fdArray);

          if (index == 0) {
               ZygoteConnection newPeer = acceptCommandPeer();
               peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
          } else {
                boolean done;

                //
                done = peers.get(index).runOnce();
                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
          }
}

 

boolean runOnce() {

     // fork调用,复制zygote进程产生子进程

     pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, parsedArgs.debugFlags, rlimits);

 

     if (pid == 0) {
          // in child
          handleChildProc(parsedArgs, descriptors, newStderr);
          // should never happen
          return true;
     } else {
          return handleParentProc(pid, descriptors, parsedArgs);
     }

}

 

private void handleChildProc(Arguments parsedArgs,
            FileDescriptor[] descriptors, PrintStream newStderr){

    // 前面Process::startViaZygote时,传入参数"--runtime-init",所以这里为true(估计是代表需要用的类已经被装入过了)

 

    if (parsedArgs.runtimeInit) {
            RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
        } else {
            ClassLoader cloader;

            if (parsedArgs.classpath != null) {
                cloader
                    = new PathClassLoader(parsedArgs.classpath,
                    ClassLoader.getSystemClassLoader());
            } else {
                cloader = ClassLoader.getSystemClassLoader();
            }

            String className;
            className = parsedArgs.remainingArgs[0];

            String[] mainArgs
                    = new String[parsedArgs.remainingArgs.length - 1];

            System.arraycopy(parsedArgs.remainingArgs, 1,
                    mainArgs, 0, mainArgs.length);

            ZygoteInit.invokeStaticMain(cloader, className, mainArgs);

        }

}

 

RuntimeInit.java

public static final void zygoteInit(String[] argv)  throws ZygoteInit.MethodAndArgsCaller {
        System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
        System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));

        commonInit();
        zygoteInitNative();

        int curArg = 0;
        for ( /* curArg */ ; curArg < argv.length; curArg++) {
            String arg = argv[curArg];

            if (arg.equals("--")) {
                curArg++;
                break;
            } else if (!arg.startsWith("--")) {
                break;
            } else if (arg.startsWith("--nice-name=")) {
                String niceName = arg.substring(arg.indexOf('=') + 1);
                Process.setArgV0(niceName);
            }
        }

        if (curArg == argv.length) {
            Slog.e(TAG, "Missing classname argument to RuntimeInit!");
            // let the process exit
            return;
        }

        // Remaining arguments are passed to the start class's static main

        String startClass = argv[curArg++];
        String[] startArgs = new String[argv.length - curArg];

        System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
        invokeStaticMain(startClass, startArgs);
}

 

private static void invokeStaticMain(String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {

        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.

        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);

        Class<?> cl;
        cl = Class.forName(className);

        Method m;
        m = cl.getMethod("main", new Class[] { String[].class });


        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */

        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

 

这之后就是ActivityThread::main被执行,产生ActivityThread对象并注册给ActivityManagerService。

 

IActivityManager是ActivityThread调用ActivityManagerServcie的功能接口

ActivityThread--->IActivityManager--->ActivityManagerServcie

 

ApplicationThread则是ActivityManagerServcie调用ActivityThread的功能接口

ActivityThread<--ApplicationThread<--ActivityManagerServcie

 

 

你可能感兴趣的:(thread,exception,android,ClassLoader,String,null)