ActivityThread的main方法在哪里被调用的?

先说结论:
MethodAndArgsCaller类继承自Exception类,并且实现了Runnable接口。在run方法里面,通过反射,也就是Method.invoke方法,完成ActivityThread.main()方法的调用。MethodAndArgsCaller类的对象是一个异常,被抛出后,被catch到,然后通过对象调用run方法。这样run方法,最终是在ZygoteInit的main方法里面调用的。

本文源码版本Android6.0 , SDK版本23

通过我的这篇文章:在线查看Android系统源码,可以快速查看在线源码。
在线源码链接:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

具体过程:
从ZygoteInit的main方法开始,到调用runOnce方法:

public static void main(String argv[]) {
    try {
        // ...代码省略...

        // 本文重点:接收命令socket连接;
        runSelectLoop(abiList);
    } catch (MethodAndArgsCaller caller) {
        caller.run();//在启动子进程的过程中(最终还是调用到这里,执行ActivityThread.main()方法)
    }
}


/**
 * 从下面的注释就可以看出:
 * 在process中运行一个loop,用于接收从新连接返回的指令(commands);
 * Runs the zygote process's select loop. Accepts new connections as
 * they happen, and reads commands from connections one spawn-request's
 * worth at a time.
 * 
 * 最后抛出MethodAndArgsCaller异常,在此异常捕获的地方执行子process的main()方法;
 * @throws MethodAndArgsCaller in a child process when a main() should
 * be executed.
 */
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
    // ...代码省略...

    // 无限轮训
    while (true) {
        // ...代码省略...

        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 {
                // 最终执行这里ZygoteConnection.runOnce()方法;
                boolean done = peers.get(i).runOnce();
                if (done) {
                    peers.remove(i);
                    fds.remove(i);
                }
            }
        }
    }
}

接着看ZygoteConnection.runOnce源码如下:

/**
 * 该方法主要做了3件事:
 * 1.读取子进程创建时,传递的参数信息;
 * 2.根据这些参数,从Zygote中fork一个子进程;
 * 3.对这个子进程进行处理;
 */
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

    // 1.readArgumentList() 读取SystemServer发送过来的参数
    //此方法,下面会贴源码
    String[] args = readArgumentList();
    if (args == null) {
        return true;
    }
    // ...代码省略...

    Arguments parsedArgs = null;
    int pid = -1;
    try {
        parsedArgs = new Arguments(args);
        // ...代码省略...

        // 2.根据参数,fork一个子进程
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                parsedArgs.appDataDir);
    } catch (Exception ex) {
        // ...
    }

    if (pid == 0) {
        // 3.处理子进程
        handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
        return true;
    }
    // ...
}

/**
 * 从指令套接字中读取参数集,然后存储在一个String数组中,并返回该数组;
 * 
 * 该方法接收来自Process.zygoteSendArgsAndGetPid()的数据,
 * 数据的传输是通过Socket进行的;
 */
private String[] readArgumentList()
        throws IOException {
    /* 
     * 为什么这里s是一个Integer类型呢?
     * 请查看:Process.zygoteSendArgsAndGetResult()
     * 这个Process类源码路径是:/frameworks/base/core/java/android/os/Process.java
     * s:代表参数的个数;
     */
    String s = mSocketReader.readLine();
    int argc = Integer.parseInt(s);
    // ...
    String[] result = new String[argc];
    for (int i = 0; i < argc; i++) {
        result[i] = mSocketReader.readLine();
        if (result[i] == null) {
            throw new IOException("truncated request");
        }
    }
    return result;
}

/**
 * 入参parsedArgs包含了className
 * 该方法实际就是调用Activity.main();
 */
private void handleChildProc(Arguments parsedArgs,
        FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
        throws ZygoteInit.MethodAndArgsCaller {
    // ...代码省略...

    if (parsedArgs.invokeWith != null) {
        WrapperInit.execApplication(parsedArgs.invokeWith, ...);
    } else {
        // 实际执行这里,其实到了这里已经很清晰了,执行过程跟SystemServer的启动一样;
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                parsedArgs.remainingArgs, null /* classLoader */);
    }
}

接着看RuntimeInit.zygoteInit方法:

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {

    applicationInit(targetSdkVersion, argv, classLoader);
}

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
    // ...省略大段代码...
	final Arguments args;
	...
    args = new Arguments(argv);
    ...
    // 启动指定类的main方法(startClass 代表要启动的类的类名)
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

/*
 * 这个方法的主要作用:
 * 将从Socket中获取的参数信息args,通过反射获取到即将要被调用的类的main()方法;
 */
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
    Class<?> cl;

    try {
        // 1.根据类名获取class对象
        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.校验main方法的修饰符是否是public static的;
    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }

    /* 
     * 上面全部满足后,new了一个异常对象,throw抛出了异常,
     * 这个异常在文章开头ZygoteInit.main()中被捕获,
     * 就是上面提示要注意的地方,在异常捕获的地方执行caller.run()方法;
     */
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

继续看看类:MethodAndArgsCaller,MethodAndArgsCaller是ZygoteInit的一个静态内部类。

public static class MethodAndArgsCaller extends Exception
            implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try {
            // mMethod就是SystemServer.main()方法;
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

小结:SystemServer传递来许多参数,ZygoteInit根据这些参数,通过反射生成Methon对象,然后调用invoke方法,执行ActivityThread.main()方法。

新的问题:SystemServer是怎么读取ActivityThread.main()方法信息的?

你可能感兴趣的:(Handler,java,android,开发语言)