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> [--] <start class name> <args>
* </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);
}
- 大小: 68.6 KB
分享到:
相关推荐
Android应用程序可以实现开机时启动相关应用 如service等 Android系统在开机启动时会发出一个系统广播"android intent action BOOT COMPLETED" 在接收到这个广播就可以实现开机自启动功能 下面就是一个...
在Android开发中,获取系统所有应用程序列表并实现点击启动应用是一项常见的需求,这通常涉及到对Android系统的应用管理和Intent机制的理解。下面将详细讲解这个过程。 首先,我们需要理解Android权限。在...
### Android应用程序启动白屏黑屏优化 #### 一、白屏黑屏现象产生的原因 在Android应用程序中,启动过程中的白屏或黑屏现象是非常常见的一个问题。这种现象通常发生在应用程序首次启动时,用户会看到一个短暂的...
总的来说,Android应用程序间的交互主要依赖于Intent对象,通过Intent我们可以启动其他应用、打开网页、发送消息等。在本例中,我们了解了如何从Program1启动Program2,以及如何在Program2退出时返回Program1。这是...
下面我们将深入探讨如何实现Android应用程序启动时背景画面的切换。 首先,理解Android的主题(Theme)和样式(Style)是至关重要的。主题是全局的应用外观,可以影响整个应用程序的视觉效果,而样式则更专注于单个...
在Android系统中,应用自启动是指应用程序在设备启动完成后自动运行的一种机制。这对于某些需要后台服务持续运行或者希望在用户开机后立即提供服务的应用来说是非常重要的。本篇将详细讲解如何实现Android应用的自...
4. 应用程序入口管理:Android 桌面应用程序需要管理应用程序的入口,包括自定义桌面启动、应用程序的安装、卸载等操作。 Android 桌面应用程序的开发需要了解以下知识点: 1. AndroidManifest.xml 文件:...
在Android平台上,应用程序之间的交互是通过Intent对象来实现的,这包括从一个应用启动另一个应用。本示例探讨了在已知和未知包名的情况下如何启动另一个应用的详细过程。 ### 已知包名的情况 #### 方法一:通过...
在Android应用开发中,"开机自启动"是一个常见的需求,特别是在需要后台服务持续运行或者希望应用程序在用户开机后立即可用的情况下。本知识点主要讲解如何利用Android的广播接收器(BroadcastReceiver)来实现在...
Android 应用程序启动优化之冷启动和热启动详解 一、应用程序启动方式 Android 应用程序的启动方式可以分为两种:冷启动和热启动。 1. 冷启动:当启动应用程序时,后台没有该应用程序的进程,这时系统会重新创建...
在Android系统中,一个应用程序启动另一个应用程序是一种常见的交互方式,这涉及到Android的组件通信机制,尤其是Activity和Intent的使用。让我们深入探讨这个话题。 首先,应用程序内的Activity跳转是Android应用...
在本文中,我们将深入探讨如何进行Android应用程序开发,特别是针对手机通信录的实现。这个项目旨在创建一个功能齐全的通信录应用,用户可以添加、删除、编辑联系人,查看联系人列表,以及直接拨打电话和发送短信给...
这里的`ACTION_MAIN`表示启动一个应用的主入口,`ComponentName`则指定了目标应用的包名和活动名。 2. Intent Filter:为了让其他App能够找到并启动你的App,你需要在AndroidManifest.xml文件中为被启动的Activity...
在Android系统中,开机自启动应用是指当设备完成启动过程后,系统会自动运行的一类应用程序。这些应用通常会在用户无须手动干预的情况下执行特定任务,例如同步数据、推送通知或者进行后台服务的初始化。"BOOT_...
本项目“Android应用源码之程序启动界面Demo”旨在提供一个关于如何创建和优化Android启动界面的实例。 一、启动界面设计原则 1. 用户体验:启动界面应该简洁、快速,避免过长的等待时间,以免影响用户体验。 2. ...
《Android应用程序开发(第三版)》是由王向辉、张国印、沈洁三位专家编著的教材,这本书深入浅出地介绍了Android平台上的应用开发技术。课件源程序是学习此书的重要辅助资料,提供了丰富的实例和练习,帮助读者更好...
本教程将详细讲解如何在Android应用中实现从一个应用跳转到另一个应用。 首先,我们需要了解Android中的Intent机制。Intent在Android系统中扮演着消息传递的角色,它用于启动活动(Activity)、服务(Service)或...
- 活动(Activity):Android应用的核心组件,代表一个可视化的用户界面。 - 意图(Intent):用于启动活动或服务,实现应用间的通信。 - 跳转与栈管理:了解Activity的启动模式,理解任务栈的概念,掌握如何正确...
Activity是Android应用程序中最基本的组件,代表用户界面的一个独立屏幕。每个Activity都是一个独立的类,继承自Activity基类。Activity负责展示用户界面,包括各种View控件,并响应用户的交互事件。一个应用程序...
在Android开发中,实现应用程序的定时自动启动是一个常见的需求,特别是在设计闹钟应用、健康监测应用或是需要定期执行后台任务的应用场景中。本文将详细解析如何利用`AlarmManager`结合`BroadcastReceiver`来达成这...