android 一个应用程序的起步

android 一个应用程序的启动android 程序启动过程,这次主要研究的是具有Activity的android app!package da

android 一个应用程序的启动
    android 程序启动过程,这次主要研究的是具有Activity的android app!

package dalvik.system;class NativeStart implements Runnable {    private NativeStart() {}    private static native void main(String[] dummy);    public native void run();}

由此部分代码通过JNI进一步激活ZygoteInit 中的main()由此一个新的Linux进程就启动了,但是在android中已经把Linux这些特新封装起来了,隐藏了linux的一些特性。只流下了:Activity、Service、ContentProvider、BroadcastReceiver。
   public static void main(String argv[]) {        try {            registerZygoteSocket();            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,                SystemClock.uptimeMillis());            preloadClasses();            preloadResources();            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                SystemClock.uptimeMillis());            // Do an initial gc to clean up after startup            gc();            // If requested, start system server directly from Zygote            if (argv.length != 2) {                throw new RuntimeException(                        "ZygoteInit.main expects two arguments");            }            if (argv[1].equals("true")) {                startSystemServer();            }            Log.i(TAG, "Accepting command socket connections");            if (ZYGOTE_FORK_MODE) {                runForkMode();            } else {                runSelectLoopMode();            }            closeServerSocket();        } catch (MethodAndArgsCaller caller) {            caller.run();        } catch (RuntimeException ex) {            Log.e(TAG, "Zygote died with exception", ex);            closeServerSocket();            throw ex;        }    }


    /**     * Helper exception class which holds a method and arguments and     * can call them. This is used as part of a trampoline to get rid of     * the initial process setup stack frames.     */    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.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);            }        }    }
当抛出MethodAndArgsCaller caller 异常时,执行:caller.run();
mMethod.invoke(null, new Object[] { mArgs });激活了ActivityThread中的main函数,因为main函数为static ,所以invoke第一个参数为null
此异常是间接由startSystemServer();throw的。如下代码:
    /**     * Prepare the arguments and fork for the system server process.     */    private static boolean startSystemServer()             throws MethodAndArgsCaller, RuntimeException {        /* Hardcoded command line to start the system server */        String args[] = {            "--setuid=1000",            "--setgid=1000",            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",            "--capabilities=130104352,130104352",            "--runtime-init",            "--nice-name=system_server",            "com.android.server.SystemServer",        };        ZygoteConnection.Arguments parsedArgs = null;        int pid;        try {            parsedArgs = new ZygoteConnection.Arguments(args);            /*             * Enable debugging of the system process if *either* the command line flags             * indicate it should be debuggable or the ro.debuggable system property             * is set to "1"             */            int debugFlags = parsedArgs.debugFlags;            if ("1".equals(SystemProperties.get("ro.debuggable")))                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;            /* Request to fork the system server process */            pid = Zygote.forkSystemServer(                    parsedArgs.uid, parsedArgs.gid,                    parsedArgs.gids, debugFlags, null);        } catch (IllegalArgumentException ex) {            throw new RuntimeException(ex);        }          /* For child process */        if (pid == 0) {            handleSystemServerProcess(parsedArgs);        }        return true;    }

    /**     * Finish remaining work for the newly forked system server process.     */    private static void handleSystemServerProcess(            ZygoteConnection.Arguments parsedArgs)            throws ZygoteInit.MethodAndArgsCaller {        /*         * First, set the capabilities if necessary         */        if (parsedArgs.uid != 0) {            try {                setCapabilities(parsedArgs.permittedCapabilities,                                parsedArgs.effectiveCapabilities);            } catch (IOException ex) {                Log.e(TAG, "Error setting capabilities", ex);            }        }        closeServerSocket();        /*         * Pass the remaining arguments to SystemServer.         * "--nice-name=system_server com.android.server.SystemServer"         */        RuntimeInit.zygoteInit(parsedArgs.remainingArgs);        /* should never reach here */    }


    /**     * The main function called when started through the zygote process. This     * could be unified with main(), if the native code in finishInit()     * were rationalized with Zygote startup.<p>     *     * Current recognized args:     * <ul>     *   <li> --nice-name=<i>nice name to appear in ps</i>     *   <li> <code> [--] &lt;start class name&gt;  &lt;args&gt;     * </ul>     *     * @param argv arg strings     */    public static final void zygoteInit(String[] argv)            throws ZygoteInit.MethodAndArgsCaller {        // TODO: Doing this here works, but it seems kind of arbitrary. Find        // a better place. The goal is to set it up for applications, but not        // tools like am.        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);    }    /**     * Invokes a static "main(argv[]) method on class "className".     * Converts various failing exceptions into RuntimeExceptions, with     * the assumption that they will then cause the VM instance to exit.     *     * @param className Fully-qualified class name     * @param argv Argument vector for main()     */    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;        try {            cl = Class.forName(className);        } catch (ClassNotFoundException ex) {            throw new RuntimeException(                    "Missing class when invoking static main " + className,                    ex);        }        Method m;        try {            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);        }        int modifiers = m.getModifiers();        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {            throw new RuntimeException(                    "Main method is not public and static on " + className);        }        /*         * 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);    }