FileDocCategorySizeDatePackage
RuntimeInit.javaAPI DocAndroid 5.1 API15384Thu Mar 12 22:22:10 GMT 2015com.android.internal.os

RuntimeInit

public class RuntimeInit extends Object
Main entry point for runtime initialization. Not for public consumption.
hide

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static boolean
initialized
true if commonInit() has been called
private static android.os.IBinder
mApplicationObject
private static volatile boolean
mCrashing
Constructors Summary
Methods Summary
private static intClog_e(java.lang.String tag, java.lang.String msg, java.lang.Throwable tr)


         
         
          

             
        return Log.println_native(Log.LOG_ID_CRASH, Log.ERROR, tag,
                msg + '\n" + Log.getStackTraceString(tr));
    
private static voidapplicationInit(int targetSdkVersion, java.lang.String[] argv, java.lang.ClassLoader classLoader)

        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        // 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);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            // let the process exit
            return;
        }

        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    
private static final voidcommonInit()

        if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");

        /* set default handler; this applies to all threads in the VM */
        Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());

        /*
         * Install a TimezoneGetter subclass for ZoneInfo.db
         */
        TimezoneGetter.setInstance(new TimezoneGetter() {
            @Override
            public String getId() {
                return SystemProperties.get("persist.sys.timezone");
            }
        });
        TimeZone.setDefault(null);

        /*
         * Sets handler for java.util.logging to use Android log facilities.
         * The odd "new instance-and-then-throw-away" is a mirror of how
         * the "java.util.logging.config.class" system property works. We
         * can't use the system property here since the logger has almost
         * certainly already been initialized.
         */
        LogManager.getLogManager().reset();
        new AndroidConfig();

        /*
         * Sets the default HTTP User-Agent used by HttpURLConnection.
         */
        String userAgent = getDefaultUserAgent();
        System.setProperty("http.agent", userAgent);

        /*
         * Wire socket tagging to traffic stats.
         */
        NetworkManagementSocketTagger.install();

        /*
         * If we're running in an emulator launched with "-trace", put the
         * VM into emulator trace profiling mode so that the user can hit
         * F9/F10 at any time to capture traces.  This has performance
         * consequences, so it's not something you want to do always.
         */
        String trace = SystemProperties.get("ro.kernel.android.tracing");
        if (trace.equals("1")) {
            Slog.i(TAG, "NOTE: emulator trace profiling enabled");
            Debug.enableEmulatorTraceOutput();
        }

        initialized = true;
    
public static final android.os.IBindergetApplicationObject()

        return mApplicationObject;
    
private static java.lang.StringgetDefaultUserAgent()
Returns an HTTP user agent of the form "Dalvik/1.1.0 (Linux; U; Android Eclair Build/MASTER)".

        StringBuilder result = new StringBuilder(64);
        result.append("Dalvik/");
        result.append(System.getProperty("java.vm.version")); // such as 1.1.0
        result.append(" (Linux; U; Android ");

        String version = Build.VERSION.RELEASE; // "1.0" or "3.4b5"
        result.append(version.length() > 0 ? version : "1.0");

        // add the model for the release build
        if ("REL".equals(Build.VERSION.CODENAME)) {
            String model = Build.MODEL;
            if (model.length() > 0) {
                result.append("; ");
                result.append(model);
            }
        }
        String id = Build.ID; // "MASTER" or "M4-rc20"
        if (id.length() > 0) {
            result.append(" Build/");
            result.append(id);
        }
        result.append(")");
        return result.toString();
    
private static voidinvokeStaticMain(java.lang.String className, java.lang.String[] argv, java.lang.ClassLoader classLoader)
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()
param
classLoader the classLoader to load {@className} with

        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);
        } 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);
    
public static final voidmain(java.lang.String[] argv)

        if (argv.length == 2 && argv[1].equals("application")) {
            if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application");
            redirectLogStreams();
        } else {
            if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting tool");
        }

        commonInit();

        /*
         * Now that we're running in interpreted code, call back into native code
         * to run the system.
         */
        nativeFinishInit();

        if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");
    
private static final native voidnativeFinishInit()

private static final native voidnativeSetExitWithoutCleanup(boolean exitWithoutCleanup)

private static final native voidnativeZygoteInit()

public static voidredirectLogStreams()
Redirect System.out and System.err to the Android log.

        System.out.close();
        System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
        System.err.close();
        System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
    
public static final voidsetApplicationObject(android.os.IBinder app)
Set the object identifying this application/process, for reporting VM errors.

        mApplicationObject = app;
    
public static voidwrapperInit(int targetSdkVersion, java.lang.String[] argv)
The main function called when an application is started through a wrapper process. When the wrapper starts, the runtime starts {@link RuntimeInit#main} which calls {@link WrapperInit#main} which then calls this method. So we don't need to call commonInit() here.

param
targetSdkVersion target SDK version
param
argv arg strings

        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from wrapper");

        applicationInit(targetSdkVersion, argv, null);
    
public static voidwtf(java.lang.String tag, java.lang.Throwable t, boolean system)
Report a serious error in the current process. May or may not cause the process to terminate (depends on system settings).

param
tag to record with the error
param
t exception describing the error site and conditions

        try {
            if (ActivityManagerNative.getDefault().handleApplicationWtf(
                    mApplicationObject, tag, system, new ApplicationErrorReport.CrashInfo(t))) {
                // The Activity Manager has already written us off -- now exit.
                Process.killProcess(Process.myPid());
                System.exit(10);
            }
        } catch (Throwable t2) {
            Slog.e(TAG, "Error reporting WTF", t2);
            Slog.e(TAG, "Original WTF:", t);
        }
    
public static final voidzygoteInit(int targetSdkVersion, java.lang.String[] argv, java.lang.ClassLoader classLoader)
The main function called when started through the zygote process. This could be unified with main(), if the native code in nativeFinishInit() were rationalized with Zygote startup.

Current recognized args:

  • [--] <start class name> <args>

param
targetSdkVersion target SDK version
param
argv arg strings

        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        redirectLogStreams();

        commonInit();
        nativeZygoteInit();

        applicationInit(targetSdkVersion, argv, classLoader);