Android的运行环境和Java运行环境有着本质的区别,在Android系统中每个应用程序都是一独立的进程,当一个进程死掉时,不会影响其它进程的运行,这能极大的保证Android系统的稳定。 Zygote守护进程的启动是Android运行环境启动的开始阶段, Zygote进程通过Linux系统特有的Fork机制分裂克隆出完全相同的运行环境,所有的Android应用程序都是Zygote进程的子进程,system_server进程作为Zygote进程的嫡长子进程,对Android系统服务又有着重要意义,本节内容是我们研究Android系统启动的开始,让我们从Zygote守护进程的启动开始分析吧。
在init.rc中,通过init进程启动了Zygote服务:
service zygote/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
……
通过上面init.rc的代码可知,Zygote服务对应程序为/system/bin/app_process,服务名为zygote,参数列表为:-Xzygote/system/bin --zygote --start-system-server。
在启动zygote 服务时,在/dev/socket/目录下建立一个streamsocket文件:zygote,权限为666。
我们可以通过下面的命令来查找Zygote进程的源码:
find ./ -nameAndroid.mk -exec grep -l app_process {}\;
注:find命令用于查找一个文件,-exec xxx {} \;表示:在前面命令的结果里执行grep 命令。
由上述命令结果可知,Zygote进程代码为frameworks/base/cmds/app_process/app_main.cpp
找到该程序的main入口函数:
118 int main(int argc,const char* const argv[])
119 {
120 // These are global variables inProcessState.cpp
121 mArgC = argc;
122 mArgV = argv;
123
124 mArgLen = 0;
125 for (int i=0; i 126 mArgLen += strlen(argv[i]) + 1; 127 } 128 mArgLen--; 129 130 AppRuntimeruntime; 131 const char *arg; 132 const char *argv0; 133 134 argv0 = argv[0]; 135 136 // Process command line arguments 137 // ignore argv[0] 138 argc--; 139 argv++; 141 // Everything up to '--' or first non '-'arg goes to the vm 142 // 在zygote服务的参数列表中:/system/bin–zygote--start-system-server // 以“--”和非“-”开头的参数,是dalvik的参数,交给Vm来处理 143 int i = runtime.addVmArguments(argc, argv); 144 145 // 找到zygote的目录:/system/bin 146 if (i < argc) { 147 runtime.mParentDir = argv[i++]; 148 } 149 150 // 如果接下来的参数是:--zygote --start-system-server的话, // 设置argv0=“zygote”,startSystemServer= true,启动java VM 151 if (i < argc) { 152 arg = argv[i++]; 153 if (0 == strcmp("--zygote",arg)) { 154 bool startSystemServer = (i 155 strcmp(argv[i],"--start-system-server") == 0 : false; 156 setArgv0(argv0,"zygote"); 157 set_process_name("zygote"); 158 runtime.start("com.android.internal.os.ZygoteInit", 159 startSystemServer); 160 } else { 161 set_process_name(argv0); 162 163 runtime.mClassName = arg; 164 165 // Remainder of args get passed tostartup class main() 166 runtime.mArgC = argc-i; 167 runtime.mArgV = argv+i; 168 169 LOGV("App process is startingwith pid=%d, class=%s.\n", 170 getpid(), runtime.getClassName()); 171 runtime.start(); 172 } 173 } else { 174 LOG_ALWAYS_FATAL("app_process: noclass name or --zygote supplied."); 175 fprintf(stderr, "Error: no classname or --zygote supplied.\n"); 176 app_usage(); 177 return 10; 178 } 179 180 }
根据service zygote的参数,启动Android运行时环境:
runtime.start("com.android.internal.os.ZygoteInit",startSystemServer),根据前面的分析可知:startSystemServer= true,runtime是AppRuntime的对象,AppRuntime是AndroidRuntime的子类,如图xx-xx所示:
图 xx-xx AndroidRuntime与AppRuntime类关系图
由上面类图可知,runtime.start方法在AndroidRuntime里实现:
@frameworks/base/core/jni/AndroidRuntime.cpp
883 void AndroidRuntime::start(const char*className, const bool startSystemServer)
884{
// logcat里最显眼的字样
885 LOGD("\n>>>>>> AndroidRuntime START %s<<<<<<\n",
886 className != NULL ? className : "(unknown)");
887
888 char* slashClassName = NULL;
889 char* cp;
890 JNIEnv* env;
891
// 启动Dalvik虚拟机,在AndroidRuntime::startVm方法中,设置了大量VM的启动参数,
// 最后通过JNI调用JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs)函数启动虚拟机
918 /* start the virtual machine */
919 if (startVm(&mJavaVM, &env) != 0)
920 goto bail;
921
922 /*
923 * Register android functions. //注册系统使用的JNI函数
924 */
925 if (startReg(env) < 0) {
926 LOGE("Unable to register all android natives\n");
927 goto bail;
928 }
930 /*
931 * We want to call main() with a String array with arguments in it.
932 * At present we only have one argument, the class name. Create an
933 * array to hold it.
934 */
935 jclass stringClass;
936 jobjectArray strArray;
937 jstring classNameStr;
938 jstring startSystemServerStr;
939
// 从虚拟机执行环境里,查找到String类
940 stringClass = env->FindClass("java/lang/String");
941 assert(stringClass != NULL);
// 创建一个String数组,有两个元素(strArray = new String[2])
942 strArray = env->NewObjectArray(2, stringClass, NULL);
943 assert(strArray != NULL);
// 创建一个Java String对象,初始值为:className的值,
// 即:“com.android.internal.os.ZygoteInit”
944 classNameStr = env->NewStringUTF(className);
945 assert(classNameStr != NULL);
// 设置strArray 第一个元素的值为:classNameStr(strArray[0] = classNameStr)
946 env->SetObjectArrayElement(strArray, 0, classNameStr);
// 创建一个Java String对象,初始值为:startSystemServer的值,即:“true”
947 startSystemServerStr = env->NewStringUTF(startSystemServer ?
948 "true" : "false");
// 设置strArray 第二个元素的值为:strArray[1]=startSystemServerStr
949 env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
// 根据上面的解释,我们可以用下面的Java代码来表示:
// String[] strArray = new strArray[2];
// strArray[0] ="com.android.internal.os.ZygoteInit"
// strArray[1] = "true"
950
951 /*
952 * Start VM. This thread becomesthe main thread of the VM, and will
953 * not return until the VM exits.
954 */
955 jclass startClass;
956 jmethodID startMeth;
957
958 slashClassName = strdup(className);
959 for (cp = slashClassName; *cp != '\0'; cp++)
960 if (*cp == '.')
961 *cp = '/';
// 将com.android.internal.os.ZygoteInit中的包分隔符“.”换成“/”
// 即:slashClassName ="com/android/internal/os/ZygoteInit"
962
963 startClass = env->FindClass(slashClassName);
// 从VM中查找ZygoteInit类,难道它要在VM里运行这个它?
964 if (startClass == NULL) {
965 LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
966 /* keep going */
967 } else {
968 startMeth = env->GetStaticMethodID(startClass, "main",
969 "([Ljava/lang/String;)V");
// 从ZygoteInit类中查找名字为main的静态方法,
// 并且main方法有一个参数String[],返回值为void。
// 这不就是Java应用程序的main函数的签名吗?难道要调用它??
970 if (startMeth == NULL) {
971 LOGE("JavaVM unable to find main() in '%s'\n", className);
972 /* keep going */
973 } else {
974 env->CallStaticVoidMethod(startClass, startMeth, strArray);
// 果然,调用了ZygoteInit类里的main方法。这不就是在VM里运行ZygoteInit程序吗!!
980 }
981 }
... 省略部分代码...
991 }
由上面的分析简单总结下:
从源码的角度在AndroidRuntime::start方法实现了下面功能:
1>通过startVm来启动Dalvik虚拟机(简称DVM),并且注册了一些本地JNI函数,由于这个时候DVM里还没有程序,只是个空的DVM执行环境
2>通过AndroidRuntime::start的参数,在JNI代码里运行第一个Java程序ZygoteInit,将其作为DVM的主线程,同时给它传递两个在JNI中构建的参数:
"com/android/internal/os/ZygoteInit"和"true"
我们再从进程的角度来分析下:
Zygote进程由init进程作为Service启动,在Zygote进程里通过startVm启动了VM执行环境(如图xx-xx中①所示),通过JNI代码在VM环境中运行ZygoteInit.java,作为VM中的主线程。
图 xx-xx Zygote进程与Dalvik虚拟机
Zygote将DVM运行环境准备好了,并且开始调用执行ZygoteInit.java代码。
下面我们分析下ZygoteInit.java代码。
@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
554 public static void main(String argv[]) {
555 try {
... 省略部分代码...
561 registerZygoteSocket(); // 注册ZygoteSocket,创建一个Socket的服务端
... 省略部分代码...
564 preloadClasses(); // 预加载类
565 //cacheRegisterMaps();
566 preloadResources(); // 预资源类
... 省略部分代码...
// 如果ZygoteInit的第二个参数为"true",则调用startSystemServer()
581 if(argv[1].equals("true")) {
582 startSystemServer();
583 } else if(!argv[1].equals("false")) {
584 throw newRuntimeException(argv[0] + USAGE_STRING);
585 }
... 省略部分代码...
603 }
根据main函数的第二个参数,调用了startSystemServer:
508 private static boolean startSystemServer()
511 String args[] = {
512 "--setuid=1000",
513 "--setgid=1000",
514"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
515 "--capabilities=130104352,130104352",
516 "--runtime-init",
517 "--nice-name=system_server",
518 "com.android.server.SystemServer",
519 };
520 ZygoteConnection.Arguments parsedArgs= null;
521
522 int pid;
523
524 try {
// 创建ZygoteConnection的内部类Arguments,它是ZygoteSocket客户端的参数封装类
// 在Arguments的构造方法里对args[]进行了解析,下面Zygote.forkSystemServer会用到。
525 parsedArgs = newZygoteConnection.Arguments(args);
... 省略部分代码...
536 /* Request to fork the system server process*/
537 pid = Zygote.forkSystemServer(
538 parsedArgs.uid,parsedArgs.gid,
539 parsedArgs.gids,debugFlags, null,
540 parsedArgs.permittedCapabilities,
541 parsedArgs.effectiveCapabilities);
// 调用Zygote的静态方法forkSystemServer(),用来创建了一个
// 名字为system_server的进程。该方法是一个本地方法
// 在libcore/dalvik/src/main/java/dalvik/system/Zygote.java里定义,
// 本地实现在dalvik/vm/native/dalvik_system_Zygote.c中
542 } catch (IllegalArgumentException ex){
543 throw new RuntimeException(ex);
544 }
545
546 /* For child process */
547 if (pid == 0) {
548 handleSystemServerProcess(parsedArgs);
549 }
550
551 return true;
552 }
通过Zygote.forkSystemServer方法克隆了一个新的进程system_server,除了进程ID号pid它和Zygote进程的代码和数据完全一样,关于克隆详细内容,请查看fork系统调用相关知识。
在新创建的子进程system_server中调用handleSystemServerProcess:
491 private static voidhandleSystemServerProcess(
492 ZygoteConnection.ArgumentsparsedArgs)
493 throwsZygoteInit.MethodAndArgsCaller {
494
// 在新创建的子进程里将ZygoteSocket关闭
495 closeServerSocket();
... 省略部分代码...
// 将"--nice-name=system_server,com.android.server.SystemServer"传递给RuntimeInit.zygoteInit()
// 在RuntimeInit.zygoteInit方法里,调用了SystemServer的main方法,即在新进程里运行SystemServer.java
501 RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
502 /* should never reach here */
503 }
至此,Zygote的第一个嫡长子进程system_server创建完毕,并且开始执行其main方法,我们做下总结,如图xx-xx所示。
图 xx-xx system_server进程的创建
①:在Zygote进程通过startVm启动Dalvik虚拟机(简称DVM),在DVM里通过JNI调用ZygoteInit.main(),启动DVM里第一个主线程。
②:在ZygoteInit.java中绑定了ZygoteSocket并预加载类和资源。
③:通过Zygote.forkSystemServer()本地方法,在Linux中分裂fork出Zygote的第一个子进程,取名为system_server,该进程中的代码和数据与父进程Zygote完全一样。
④:在Zygote进程中通过RuntimeInit.zygoteInit(),调用SystemServer.main(),从而在system_server中运行SystemServer.java代码。
在Zygote进程创建时,init.rc脚本中创建了/dev/socket/zygote文件,它在ZygoteInit中被绑定为服务器端,用来接收克隆Zygote进程的请求,它对应用程序的创建有着重要的意义,其创建过程如下图所示:
图 xx-xx 应用程序的创建
① Zygote进程绑定并通过select监听ZygoteSocket(/dev/socket/zygote)
② 其它进程发出socket连接请求,用于创建新应用程序
③ Zygote和请求发起者建立新连接用于通信,接收待创建应用程序信息
④:Zygote进程根据客户端数据请求Fork出新的子进程
在ZygoteInit中预加载类和预加资源对Android整个运行环境有着至关重要的意义,预加载的类是指大量的Android框架层代码,这些类有数千个,当Android应用程序运行时都要加载这些类,同样的预加载资源是指一些系统的图片、图标、字符串资源。如果这些类和资源推迟到Android应用程序启动时,那么应用程序的启动速度会大大降低,会直接影响用户体验,Android充分利用了Linux中fork进程时会克隆父进程数据和代码的特点,将类和资源提前加载到父进程里,从而大大提高了启动速度。
@frameworks/base/services/java/com/android/server/SystemServer.java
596 native public static void init1(String[] args); // init1方法为本地方法
598 public static void main(String[] args) {
... 省略部分代码...
// 加载本地库android_servers,添头加尾后本地库文件名为:libandroid_servers.so
624 System.loadLibrary("android_servers");
625 init1(args);
626 }
在system_server进程里加载了libandroid_servers.so本地库,根据JNI机制,当Java代码中通过System.load加载一个本地动态库时,会自动调用该动态库中的JNI_Onload方法,通常在JNI_Onload方法中注册本地函数与Java方法映射关系:
@frameworks/base/services/jni/onload.cpp
20 extern "C" jint JNI_OnLoad(JavaVM*vm, void* reserved)
21 {
22 JNIEnv* env = NULL;
23 jint result = -1;
24
25 if (vm->GetEnv((void**) &env,JNI_VERSION_1_4) != JNI_OK) {
26 LOGE("GetEnv failed!");
27 return result;
28 }
29 LOG_ASSERT(env, "Could not retrievethe env!");
30
31 register_android_server_PowerManagerService(env);
32 register_android_server_InputManager(env);
33 register_android_server_LightsService(env);
34 register_android_server_AlarmManagerService(env);
35 register_android_server_BatteryService(env);
36 register_android_server_UsbService(env);
37 register_android_server_VibratorService(env);
38 register_android_server_SystemServer(env);// 它实现在com_android_server_SystemServer.cpp中
39 register_android_server_location_GpsLocationProvider(env);
40
41 return JNI_VERSION_1_4;
42 }
@frameworks/base/services/jni/com_android_server_SystemServer.cpp
22namespace android {
23
24 extern"C" int system_init();
25
26 staticvoid android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
27 {
28 system_init();// 被SystemServer.java调用,在frameworks/base/cmds/system_server/library/system_init.cpp中实现
// system_init.cpp被编译成libsystem_server.so库,被libandroid_servers.so引用
29 }
30
31 /*
32 * JNI registration.
33 */
// 由此可见,SystemServer.java中调用的init1方法,映射到了android_server_SystemServer_init1方法
34 staticJNINativeMethod gMethods[] = {
35 /* name, signature, funcPtr */
36 { "init1","([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1},
37 };
38 // 该方法被frameworks/base/services/jni/onload.cpp回调,用来注册本地方法与Java方法的映射
39 intregister_android_server_SystemServer(JNIEnv* env)
40 {
41 return jniRegisterNativeMethods(env,"com/android/server/SystemServer",
42 gMethods, NELEM(gMethods));
43 }
44
45 }; //namespace android
在register_android_server_SystemServer方法中注册本地方法与Java方法,通过映射关系可知,Java层的init1方法调用了本地的system_init方法:
@frameworks/base/cmds/system_server/library/system_init.cpp
54 extern"C" status_t system_init()
55 {
56 LOGI("Entered system_init()");
... 省略部分代码...
66 char propBuf[PROPERTY_VALUE_MAX];
67 property_get("system_init.startsurfaceflinger", propBuf,"1");
68 if (strcmp(propBuf, "1") == 0) {
69 // Start the SurfaceFlinger
70 SurfaceFlinger::instantiate(); // 启动SurfaceFlinger本地系统服务
71 }
72
73 // Start the sensor service
74 SensorService::instantiate(); // 启动SensorService本地系统服务
... 省略部分代码...
99 LOGI("System server: starting Android runtime.\n");
100
101 AndroidRuntime* runtime = AndroidRuntime::getRuntime();
102
103 LOGI("System server: starting Android services.\n");
104 runtime->callStatic("com/android/server/SystemServer","init2"); // 调用Java环境中SystemServer.java的init2方法
... 省略部分代码...
115 return NO_ERROR;
116 }
在system_init方法里开启了几个本地系统服务:SurfaceFlinger和SensorService,然后从本地又调回了Java运行环境中的SystemServer.java中的init2方法,之所以这么做,原因是上层Android系统服务的运行要依赖于本地系统服务的运行,所以system_server先保障本地服务的运行,然后再回运行Android系统服务。
SystemServer.java中的init2方法执行:
628 public static final void init2() {
629 Slog.i(TAG, "Entered the Android system server!");
630 Thread thr = new ServerThread();
631 thr.setName("android.server.ServerThread");
632 thr.start();
633 }
在init2中创建并开启了一个线程ServerThread,在线程的Run方法中
59 class ServerThread extends Thread {
... 省略部分代码...
80 @Override
81 public void run() {
// 开启主线程消息队列
85 Looper.prepare();
... 省略部分代码...
131 // Critical services...
132 try {
//添加Android系统服务
133 Slog.i(TAG, "Entropy Service");
134 ServiceManager.addService("entropy", new EntropyService());
//添加Android系统服务
136 Slog.i(TAG, "Power Manager");
137 power = new PowerManagerService();
138 ServiceManager.addService(Context.POWER_SERVICE, power);
//添加Android系统服务
140 Slog.i(TAG, "Activity Manager");
141 context = ActivityManagerService.main(factoryTest);
//添加Android系统服务
143 Slog.i(TAG, "TelephonyRegistry");
144 ServiceManager.addService("telephony.registry", newTelephonyRegistry(context));
145
... 省略部分代码,添加了大量Android系统服务...
473 // It is now time to start up the app processes...
474
475 if (devicePolicy != null) {
476 devicePolicy.systemReady();
477 }
478
479 if (notification != null) {
480 notification.systemReady();
481 }
482
483 if (statusBar != null) {
484 statusBar.systemReady();
485 }
486 wm.systemReady();
487 power.systemReady();
488 try {
489 pm.systemReady();
490 } catch (RemoteException e) {
491 }
... 省略部分代码...
507 // We now tell the activitymanager it is okay to run third party
508 // code. It will call back intous once it has gotten to the state
509 // where third party code can really run (but before it has actually
510 // started launching the initial applications), for us to complete our
511 // initialization.
512 ((ActivityManagerService)ActivityManagerNative.getDefault())
513 .systemReady(new Runnable(){ // 调用ActivityManagerService的systemReady,通知系统准备就绪。
...省略部分代码...
});
542 Looper.loop(); // system_service主线程队列开始循环等待消息
543 Slog.d(TAG, "System ServerThread is exiting!");
544 }
545 }
由前面分析可知,system_server进程的主要作用就是启动并运行Android系统服务,这些服务运行在system_server进程中,由此可见其重要性。
图x-x system_server进程
Android系统中服务分为两种:本地服务和Android系统服务,我们将Android2.3系统中这些服务分别罗列出来,以供参考。
Ø 本地服务主要包含:
服务名 |
作用 |
SurfaceFlinger |
显示层混合器 |
SensorService |
传感器服务 |
AudioFlinger |
音频管理 |
MediaPlayerService |
多媒体播放器服务 |
CameraService |
摄像头服务 |
AudioPolicyService |
音频策略管理服务 |
Ø Android系统服务:
服务名 |
作用 |
EntropyService |
提供熵服务,用于产生随机数 |
PowerManagerService |
电源管理服务 |
ActivityManagerService |
管理Activity画面 |
TelephonyRegistry |
注册电话模块的事件响应 |
PackageManagerService |
程序包管理服务 |
AccountManagerService |
联系人账户管理服务 |
ContentService |
ContentProvider服务,提供跨进程数据共享 |
BatteryService |
电池管理服务 |
LightsService |
自然光强度感应传感器服务 |
VibratorService |
震动器服务 |
AlarmManagerService |
定时器管理服务 |
WindowManagerService |
窗口管理服务 |
BluetoothService |
蓝牙服务 |
DevicePolicyManagerService |
提供一些系统级别的设置及属性 |
StatusBarManagerService |
状态栏管理服务 |
ClipboardService |
系统剪切板服务 |
InputMethodManagerService |
输入法管理服务 |
NetStatService |
网络状态服务 |
NetworkManagementService |
网络管理服务 |
ConnectivityService |
网络连接管理服务 |
ThrottleService |
节流阀控制服务 |
AccessibilityManagerService |
辅助管理程序截获所有的用户输入,并根据这些输入给用户一些额外的反馈,起到辅助的效果,View的点击、焦点等事件分发管理服务 |
MountService |
磁盘加载服务 |
NotificationManagerService |
通知管理服务,通常和StatusBarManagerService |
DeviceStorageMonitorService |
存储设备容量监听服务 |
LocationManagerService |
位置管理服务 |
SearchManagerService |
搜索管理服务 |
DropBoxManagerService |
系统日志文件管理服务 |
WallpaperManagerService |
壁纸管理服务 |
AudioService |
AudioFlinger上层的封装的音量控制管理服务 |
UsbService |
USB Host和device管理服务 |
UiModeManagerService |
UI模式管理服务,监听车载、座机等场合下UI的变化 |
BackupManagerService |
备份服务 |
AppWidgetService |
应用桌面部件服务 |
RecognitionManagerService |
身份识别服务 |
DiskStatsService |
磁盘统计服务 |
当Android系统服务启动完毕后,system_service进程会通知Android系统服务系统启动完毕,在ActivityManagerService.systemReady方法里会启动Android系统桌面应用程序:launcher。
@frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
386 public ActivityStack mMainStack;
... 省略部分代码...
6089 public void systemReady(final Runnable goingCallback) {
... 省略部分代码...
6254 synchronized (this) {
... 省略部分代码...
6288 mMainStack.resumeTopActivityLocked(null); // 在Activity栈中显示栈顶的Activity画面
6289 }
6290 }
在ActivityManagerService中维护了一个ActivityStack,它用来管理Activity的运行状态,在栈顶的Activity即是正在运行的画面,当ActivityManagerService准备就绪后,显示ActivityStack中栈顶画面。
@frameworks/base/services/java/com/android/server/am/ActivityStack.java
125 final ActivityManagerService mService;
...省略部分代码...
1051 final boolean resumeTopActivityLocked(ActivityRecord prev) {
1052 // Find the first activity that is not finishing.
// 返回ActivityStack栈顶的Activity,由于刚启动Android系统,所以返回null
1053 ActivityRecord next = topRunningActivityLocked(null);
...省略部分代码...
1060 if (next == null) {
1061 // There are no more activities! Let's just start up the
1062 // Launcher...
1063 if (mMainStack) {
1064 return mService.startHomeActivityLocked(); // 如果Activity栈顶没有Activity,则启动Launcher,即:HOME
1065 }
1066 }
由于Android系统刚启动,ActivityStack栈中还没有任何运行的Activity,所以这时要启动HOME应用程序作为主画面,从而显示桌面应用程序。
在Android中,启动一个Activity有两种方式:显示Intent启动和隐式Intent启动。
显示Intent启动:在Intent对象中指定Intent对象的接收者,是点对点的启动方式。
隐式Intent启动:类似于广播机制,在发送的Intent中通过Action和Category来匹配接收者,因此在Android系统中允许发出的Intent对象启动多个Activity,这种方式保证了Android中所有应用程序的公平性。
Android的HOME应用程序的启动是通过隐式Intent启动的,我们可以查看HOME应用程序的AndroidManifest.xml文件来确定它的Intent对象的匹配内容:
@packages/apps/Launcher2/AndroidManifest.xml
1
... 省略部分代码...
20 21 xmlns:android="http://schemas.android.com/apk/res/android" 22 package="com.android.launcher" 23 android:sharedUserId="@string/sharedUserId" 24 > 65 66 android:name="com.android.launcher2.LauncherApplication" 67 android:process="@string/process" 68 android:label="@string/application_name" 69 android:icon="@drawable/ic_launcher_home"> 70 71 72 android:name="com.android.launcher2.Launcher" 73 android:launchMode="singleTask" 74 android:clearTaskOnLaunch="true" 75 android:stateNotNeeded="true" 76 android:theme="@style/Theme" 77 android:screenOrientation="nosensor" 78 android:windowSoftInputMode="stateUnspecified|adjustPan"> 79 80 81 82 83 84 85
在Android系统启动的最终阶段通过Intent对象启动HOME应用程序,该Intent中封装了两个主要的属性:action=”android.intent.action.MAIN”,category=“android.intent.category.HOME”,通过上面的代码可以看出来,launcher2应用程序的intent-filter匹配项里包含了HOME应用程序启动的“必要条件”。