Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 高級開發 >> android 一個應用程序的啟動

android 一個應用程序的啟動

編輯:高級開發

 android 程序啟動過程,這次主要研究的是具有Activity的android app!

  Java代碼 收藏代碼

  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。

  Java代碼 收藏代碼

  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;

  }

  }

  Java代碼 收藏代碼

  /**

  * 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的。如下代碼:

  Java代碼 收藏代碼

  /**

  * 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;

  }

  Java代碼 收藏代碼

  /**

  * 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 */

  接上頁

  }

  Java代碼 收藏代碼

  /**

  * 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.

  *

  * Current recognized args:

  *

      *

  • --nice-name=nice name to appear in ps

      *

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

      *

  *

  * @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);

  }

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved