Zygote完全解析(2)

引言

Zygote完全解析(1)一文中对于Zygote的产生,Zygote孵化进程的原理以及ZygoteInit完成的工作进行了分析。文章的最后,提到了ZygoteInit的main()方法完成的功能如下:

zygote_main

本文将详细分析ZygoteInit.main()方法中的主要4项工作是如何完成的。

1.绑定socket

registerZygoteSocket()方法的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Registers a server socket for zygote command connections
*
* @throws RuntimeException when open fails
*/
private static void registerZygoteSocket() {
if (sServerSocket == null) {
int fileDesc;
try {
String env = System.getenv(ANDROID_SOCKET_ENV);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(
ANDROID_SOCKET_ENV + " unset or invalid", ex);
}
try {
sServerSocket = new LocalServerSocket(
createFileDescriptor(fileDesc));
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}

代码非常简单,主要就是先获取socket的文件描述符,然后据此创建一个LocalServerSocket对象并将其赋值给sServerSocket静态变量。

在System.getenv(ANDROID_SOCKET_ENV); 中的套接字由init进程记录在ANDROID_SOCKET_ENV环境变量中,在init.rc中有生成该socket的相关内容,如下所示:

1
2
3
4
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on

第一行在上一篇博客中已经说明过了,第二行是socket的名称、种类、访问权限,后面两行到以后再进行说明。

2.预加载应用程序Framework中的类与平台资源

2.1 预加载应用程序Framework中的类

ZygoteInit类会调用proloadClasses()与preloadResources()两个方法,这两个方法分别用于将应用程序Framework中的类,以及图标、图像、字符串等资源加载到内存中,并对装载的类与资源生成链接信息。新生成的Android应用程序在使用这些已经装载的类或资源时,直接使用即可,不需要重新生成链接信息。

此外,还加载许多其他的类,比如图形相关的类andriod.graphics,以及通信相关的类android.net等。

preloadClasses()方法的主要代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
...
private static final String PRELOADED_CLASSES="preloaded-classes";
...
private static void preloadClasses(){
...
//code_1
InputStream is=ZygoteInit.class.getClassLoader().getResourceAsStream(PRELOADED_CLASSES);
...
//code_2
BufferedReader br=new BufferedReader(new InputStreamReader(is),256);
int count=0;
String line;
while((line=br.readLine())!=null){
//code_3
line=line.trim();
if(line.startsWith("#")||line.equals("")){
continue;
}
...
//code_4
Class.forName(line);
...
}
}

在code_1处获取一个输入流,以便读取”preloaded-classes”文件(frameworks/base/preloaded-classes)中记录的类,该文件的部分内容如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Classes which are preloaded by com.android.internal.os.ZygoteInit.
# Automatically generated by frameworks/base/tools/preload/WritePreloadedClassFile.java.
# MIN_LOAD_TIME_MICROS=1250
android.R$styleable
android.accounts.AccountManager
android.accounts.AccountManager$4
android.accounts.AccountManager$6
android.accounts.AccountManager$AmsTask
android.accounts.AccountManager$BaseFutureTask
android.accounts.AccountManager$Future2Task
android.accounts.AuthenticatorDescription
android.accounts.IAccountAuthenticatorResponse$Stub
android.accounts.IAccountManager$Stub
android.accounts.IAccountManagerResponse$Stub
android.app.Activity
android.app.ActivityGroup
android.app.ActivityManager$RunningAppProcessInfo
android.app.ActivityManager$RunningServiceInfo
android.app.ActivityManagerNative
android.app.ActivityManagerProxy
android.app.ActivityThread
android.app.ActivityThread$ApplicationThread
android.app.ActivityThread$H
android.app.AlertDialog
android.app.ApplicationThreadNative
android.app.ContextImpl
android.app.ContextImpl$ApplicationPackageManager
android.app.DatePickerDialog
android.app.Dialog
android.app.ExpandableListActivity
android.app.IActivityManager
android.app.IActivityManager$ContentProviderHolder
android.app.IAlarmManager$Stub
android.app.IStatusBar$Stub
android.app.ITransientNotification$Stub
android.app.Instrumentation
android.app.IntentService
android.app.ListActivity
android.app.LocalActivityManager
android.app.Notification
android.app.PendingIntent
android.app.ProgressDialog
android.app.ResultInfo
android.app.SearchDialog
android.app.SearchDialog$SearchAutoComplete
android.app.SearchDialog$SearchBar
android.app.SearchableInfo

总共有1265个类会被预加载,可以想象一下,如果每启动一个应用程序,就加载一遍这些类,那么将会耗费巨大的时间(感兴趣的读者可以打上log进行测试)。

2.2 预加载应用程序Framework中的资源

在Android应用程序Framework中使用的字符串、颜色、图像文件、音频文件等都被称为资源。应用程序不能直接访问这些资源,需要通过Android开发工具自动生成的R类来访问。与预加载类相似,Android应用程序也会预先加载使用的资源,这样在使用这些资源时的效率会大大提高。

preloadResources()方法的代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* Load in commonly used resources, so they can be shared across
* processes.
*
* These tend to be a few Kbytes, but are frequently in the 20-40K
* range, and occasionally even larger.
*/
private static void preloadResources() {
final VMRuntime runtime = VMRuntime.getRuntime();
Debug.startAllocCounting();
try {
runtime.gcSoftReferences();
runtime.runFinalizationSync();
mResources = Resources.getSystem();
mResources.startPreloading();
if (PRELOAD_RESOURCES) {
Log.i(TAG, "Preloading resources...");
long startTime = SystemClock.uptimeMillis();
TypedArray ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_drawables);
//code_1
int N = preloadDrawables(runtime, ar);
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
startTime = SystemClock.uptimeMillis();
ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_color_state_lists);
//code_2
N = preloadColorStateLists(runtime, ar);
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
}
mResources.finishPreloading();
} catch (RuntimeException e) {
Log.w(TAG, "Failure preloading resources", e);
} finally {
Debug.stopAllocCounting();
}
}

加载资源时,有时会出现因重复调用而造成资源重复加载的情形,为了避免出现这种情况,定义了一个成员变量,用来记录资源加载的状态。若指定资源已经被加载,就会抛出IllegalStateException,并终止方法的执行。

接下来,在code_1和code_2处加载Drawable与Color State资源,frameworks/base/core/res/res/values/arrays.xml文件中记录的preloaded_drawables与preloaded_color_state_lists会被加载到内存中。代码中的M,N分别表示加载的Drawable和Color State资源的个数,打log可以进行查看,也可以查看到加载这些资源所耗费的时间(非常惊人).

3.启动SystemServer

startSystemServer()的代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
* 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 */
//code_1
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 */
//code_2
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
//code_3
handleSystemServerProcess(parsedArgs);
}
return true;
}
  • 1)args[]数组中保存了SystemServer的启动参数,参数的含义也很好理解,无非是为SystemServier设置名称、uid和gid,以及进程分组等。在字符串数组中,最后一个参数com.android.server.SystemServer用于指定SystemServer类;

  • 2)与运行其他应用程序不同,startSystemServer()方法会调用forkSystemServer()方法来创建新进程,并运行SystemServer.系统在运行普通的Android应用程序时,只负责创建应用程序进程,至于进程是否创建成功则并不检查。但是SystemServer则是必须运行的,因此在forkSystemServer()方法中必须检查生成SystemServer进程工作是否正常;

  • 3)code_3处,这个调用比较复杂,首先是handleSystemServerProcess()方法的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* 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 */
}

注释已经写得很清楚了,主要作用就是为新fork的进程完成遗留的工作,再跟踪RuntimeInit.zygoteInit()方法,其代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* 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);
}

其中commonInit()和zygoteInitNative()都是完成一些zygote的初始化工作,感兴趣的读者可以自己去看源码,此处不展开来讲。注意最后一句代码,是调用传入的Java类的main()方法,而在这里就是com.android.server.SystemServer类的main()方法,其代码如下:

1
2
3
4
5
6
7
public static void main(String[]args){
//The system server has to run all of the time, so it needs to be
//as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
System.loadLibrary("android_servers");
init1(args);
}

显然,main()方法中主要就是对于目标栈进行了优化,同时加载了android_servers这个native库,加载它的目的是调用init1()这个native方法。
init1()方法的声明如下:

1
2
3
4
5
6
/**
*This method is called from Zygote to initialize to the system. This will cause the native
*services (SurfaceFlinger, AudioFlinger, etc...) to be started. After that it will call back
*up into init2() to start the Android services.
*/
native public static void init1(String[]args);

注释已经说得非常清楚了,就不再解释它的作用了。为了寻找它对应的方法,我们找到了framework/base/service/jni/Android.mk,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
com_android_server_AlarmManagerService.cpp \
com_android_server_BatteryService.cpp \
com_android_server_KeyInputQueue.cpp \
com_android_server_LightsService.cpp \
com_android_server_SensorService.cpp \
com_android_server_SystemServer.cpp \
com_android_server_VibratorService.cpp \
onload.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware \
libhardware_legacy \
libnativehelper \
libsystem_server \
libutils \
libui
ifeq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_OS),linux)
ifeq ($(TARGET_ARCH),x86)
LOCAL_LDLIBS += -lpthread -ldl -lrt
endif
endif
endif
ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
endif
LOCAL_MODULE:= libandroid_servers
include $(BUILD_SHARED_LIBRARY)

注意底部的libandroid_servers,说明这正是我们要找的mk文件,而它对应的源文件中显然onload.cpp是含有JNI_OnLoad()函数的源文件,下面是onload.cpp的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
include "JNIHelp.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"
namespace android {
int register_android_server_AlarmManagerService(JNIEnv* env);
int register_android_server_BatteryService(JNIEnv* env);
int register_android_server_KeyInputQueue(JNIEnv* env);
int register_android_server_LightsService(JNIEnv* env);
int register_android_server_SensorService(JNIEnv* env);
int register_android_server_VibratorService(JNIEnv* env);
int register_android_server_SystemServer(JNIEnv* env);
};
using namespace android;
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("GetEnv failed!");
return result;
}
LOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_KeyInputQueue(env);
register_android_server_LightsService(env);
register_android_server_AlarmManagerService(env);
register_android_server_BatteryService(env);
register_android_server_SensorService(env);
register_android_server_VibratorService(env);
register_android_server_SystemServer(env);
return JNI_VERSION_1_4;
}

显然,我们要找的是register_android_server_SystemServer(env);这个函数(其他几个都是加载具体的本地服务方法映射),register_android_server_SystemServer()函数的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <utils/Log.h>
#include <utils/misc.h>
#include "jni.h"
#incude "JNIHelp.h"
namespace android{
extern "C" int system_init();
static void android_server_SystemServer_init1(JNIEnv*env,jobject clazz)
{
system.init();
}
/*
*JNI registeration
*/
static JNINativeMethod gMethods[]={
/*name,signature,funcPtr*/
{"init1","([Ljava/lang/String;)V",(void*)android_server_SystemServer_init1},
}
int register_android_server_SystemServer(JNIEnv*env)
{
return jniRegisterNativeMethods(env,"com/android/server/SystemServer",
gMethods,NELEM(gMethods));
}
};

显然,SystemServer中的init1()方法对应的native方法是android_server_SystemServer_init()方法,而该方法调用的是system_init()方法,而这个system_init()方法在frameworks/base/cmds/system_server/library/system_init.cpp中,其源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
* System server main initialization.
*
* The system server is responsible for becoming the Binder
* context manager, supplying the root ServiceManager object
* through which other services can be found.
*/
#define LOG_TAG "sysproc"
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/TextOutput.h>
#include <utils/Log.h>
#include <SurfaceFlinger.h>
#include <AudioFlinger.h>
#include <CameraService.h>
#include <AudioPolicyService.h>
#include <MediaPlayerService.h>
#include <android_runtime/AndroidRuntime.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <cutils/properties.h>
using namespace android;
namespace android {
/**
* This class is used to kill this process when the runtime dies.
*/
class GrimReaper : public IBinder::DeathRecipient {
public:
GrimReaper() { }
virtual void binderDied(const wp<IBinder>& who)
{
LOGI("Grim Reaper killing system_server...");
kill(getpid(), SIGKILL);
}
};
} // namespace android
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
//code_1
SurfaceFlinger::instantiate();
}
// On the simulator, audioflinger et al don't get started the
// same way as on the device, and we need to start them here
//code_2
if (!proc->supportsProcesses()) {
// Start the AudioFlinger
AudioFlinger::instantiate();
// Start the media playback service
MediaPlayerService::instantiate();
// Start the camera service
CameraService::instantiate();
// Start the audio policy service
AudioPolicyService::instantiate();
}
// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
LOGI("System server: starting Android services.\n");
//code_3
runtime->callStatic("com/android/server/SystemServer", "init2");
// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
}
  • 1)启动了Surface Flinger服务,Surface Flinger是基于C++的服务,而System Server是Java进程,它不能直接调用Surface Flinger服务。因而System Server必须经由JNI通过调用system_init()函数来运行Surface Flinger服务。
  • 2)要完全读懂这段源码,需要等学习完Binder IPC机制之后。 简单地说就是如果是模拟器,则在这里启动并注册AudioFlinger,MediaPlayerService,CameraService,AudioPolicyService(真机的话是在main_mediaserver.cpp中启动这些服务);
  • 3)那么剩下的主要就是调用SystemServer的init2()方法了。其中callStatic()函数是JNI包装函数,它允许在C++代码中经由JNI调用Java类的静态方法。

下面我们看一下init2()方法:

1
2
3
4
5
6
public static final void init2(){
Slog.i(TAG,"Entered the Android system server!");
Thread thr=new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}

init2()的代码非常简单,就是新建并运行一个ServerThread,下面我们看一下ServerThread的run()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
@Override
public void run() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
SystemClock.uptimeMillis());
Looper.prepare();
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
BinderInternal.disableBackgroundScheduling(true);
String factoryTestStr = SystemProperties.get("ro.factorytest");
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
: Integer.parseInt(factoryTestStr);
LightsService lights = null;
PowerManagerService power = null;
BatteryService battery = null;
ConnectivityService connectivity = null;
IPackageManager pm = null;
Context context = null;
WindowManagerService wm = null;
BluetoothService bluetooth = null;
BluetoothA2dpService bluetoothA2dp = null;
HeadsetObserver headset = null;
DockObserver dock = null;
UiModeManagerService uiMode = null;
RecognitionManagerService recognition = null;
ThrottleService throttle = null;
// Critical services...
try {
Slog.i(TAG, "Entropy Service");
ServiceManager.addService("entropy", new EntropyService());
Slog.i(TAG, "Power Manager");
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
Slog.i(TAG, "Telephony Registry");
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
AttributeCache.init(context);
Slog.i(TAG, "Package Manager");
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF);
ActivityManagerService.setSystemProcess();
mContentResolver = context.getContentResolver();
// The AccountManager must come before the ContentService
try {
Slog.i(TAG, "Account Manager");
ServiceManager.addService(Context.ACCOUNT_SERVICE,
new AccountManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Account Manager", e);
}
Slog.i(TAG, "Content Manager");
ContentService.main(context,
factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
Slog.i(TAG, "System Content Providers");
ActivityManagerService.installSystemProviders();
Slog.i(TAG, "Battery Service");
battery = new BatteryService(context);
ServiceManager.addService("battery", battery);
Slog.i(TAG, "Lights Service");
lights = new LightsService(context);
Slog.i(TAG, "Vibrator Service");
ServiceManager.addService("vibrator", new VibratorService(context));
// only initialize the power service after we have started the
// lights service, content providers and the battery service.
power.init(context, lights, ActivityManagerService.getDefault(), battery);
Slog.i(TAG, "Alarm Manager");
AlarmManagerService alarm = new AlarmManagerService(context);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);
Slog.i(TAG, "Init Watchdog");
Watchdog.getInstance().init(context, battery, power, alarm,
ActivityManagerService.self());
// Sensor Service is needed by Window Manager, so this goes first
Slog.i(TAG, "Sensor Service");
ServiceManager.addService(Context.SENSOR_SERVICE, new SensorService(context));
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
((ActivityManagerService)ServiceManager.getService("activity"))
.setWindowManager(wm);
// Skip Bluetooth if we have an emulator kernel
// TODO: Use a more reliable check to see if this product should
// support Bluetooth - see bug 988521
if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
Slog.i(TAG, "Registering null Bluetooth Service (emulator)");
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);
} else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
Slog.i(TAG, "Registering null Bluetooth Service (factory test)");
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);
} else {
Slog.i(TAG, "Bluetooth Service");
bluetooth = new BluetoothService(context);
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
bluetooth.initAfterRegistration();
bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
bluetoothA2dp);
int bluetoothOn = Settings.Secure.getInt(mContentResolver,
Settings.Secure.BLUETOOTH_ON, 0);
if (bluetoothOn > 0) {
bluetooth.enable();
}
}
} catch (RuntimeException e) {
Slog.e("System", "Failure starting core service", e);
}
DevicePolicyManagerService devicePolicy = null;
StatusBarService statusBar = null;
InputMethodManagerService imm = null;
AppWidgetService appWidget = null;
NotificationManagerService notification = null;
WallpaperManagerService wallpaper = null;
LocationManagerService location = null;
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
Slog.i(TAG, "Device Policy");
devicePolicy = new DevicePolicyManagerService(context);
ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DevicePolicyService", e);
}
try {
Slog.i(TAG, "Status Bar");
statusBar = new StatusBarService(context);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting StatusBarService", e);
}
try {
Slog.i(TAG, "Clipboard Service");
ServiceManager.addService(Context.CLIPBOARD_SERVICE,
new ClipboardService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Clipboard Service", e);
}
try {
Slog.i(TAG, "Input Method Service");
imm = new InputMethodManagerService(context, statusBar);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Input Manager Service", e);
}
try {
Slog.i(TAG, "NetStat Service");
ServiceManager.addService("netstat", new NetStatService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting NetStat Service", e);
}
try {
Slog.i(TAG, "NetworkManagement Service");
ServiceManager.addService(
Context.NETWORKMANAGEMENT_SERVICE, new NetworkManagementService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting NetworkManagement Service", e);
}
try {
Slog.i(TAG, "Connectivity Service");
connectivity = ConnectivityService.getInstance(context);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Connectivity Service", e);
}
try {
Slog.i(TAG, "Throttle Service");
throttle = new ThrottleService(context);
ServiceManager.addService(
Context.THROTTLE_SERVICE, throttle);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting ThrottleService", e);
}
try {
Slog.i(TAG, "Accessibility Manager");
ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
new AccessibilityManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Accessibility Manager", e);
}
try {
/*
* NotificationManagerService is dependant on MountService,
* (for media / usb notifications) so we must start MountService first.
*/
Slog.i(TAG, "Mount Service");
ServiceManager.addService("mount", new MountService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Mount Service", e);
}
try {
Slog.i(TAG, "Notification Manager");
notification = new NotificationManagerService(context, statusBar, lights);
ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Notification Manager", e);
}
try {
Slog.i(TAG, "Device Storage Monitor");
ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
new DeviceStorageMonitorService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DeviceStorageMonitor service", e);
}
try {
Slog.i(TAG, "Location Manager");
location = new LocationManagerService(context);
ServiceManager.addService(Context.LOCATION_SERVICE, location);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Location Manager", e);
}
try {
Slog.i(TAG, "Search Service");
ServiceManager.addService(Context.SEARCH_SERVICE,
new SearchManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Search Service", e);
}
if (INCLUDE_DEMO) {
Slog.i(TAG, "Installing demo data...");
(new DemoThread(context)).start();
}
try {
Slog.i(TAG, "DropBox Service");
ServiceManager.addService(Context.DROPBOX_SERVICE,
new DropBoxManagerService(context, new File("/data/system/dropbox")));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DropBoxManagerService", e);
}
try {
Slog.i(TAG, "Wallpaper Service");
wallpaper = new WallpaperManagerService(context);
ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Wallpaper Service", e);
}
try {
Slog.i(TAG, "Audio Service");
ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Audio Service", e);
}
try {
Slog.i(TAG, "Headset Observer");
// Listen for wired headset changes
headset = new HeadsetObserver(context);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting HeadsetObserver", e);
}
try {
Slog.i(TAG, "Dock Observer");
// Listen for dock station changes
dock = new DockObserver(context, power);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DockObserver", e);
}
try {
Slog.i(TAG, "UI Mode Manager Service");
// Listen for dock station changes
uiMode = new UiModeManagerService(context);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting UiModeManagerService", e);
}
try {
Slog.i(TAG, "Backup Service");
ServiceManager.addService(Context.BACKUP_SERVICE,
new BackupManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Backup Service", e);
}
try {
Slog.i(TAG, "AppWidget Service");
appWidget = new AppWidgetService(context);
ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting AppWidget Service", e);
}
try {
Slog.i(TAG, "Recognition Service");
recognition = new RecognitionManagerService(context);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Recognition Service", e);
}
try {
com.android.server.status.StatusBarPolicy.installIcons(context, statusBar);
} catch (Throwable e) {
Slog.e(TAG, "Failure installing status bar icons", e);
}
try {
Slog.i(TAG, "DiskStats Service");
ServiceManager.addService("diskstats", new DiskStatsService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting DiskStats Service", e);
}
}
// make sure the ADB_ENABLED setting value matches the secure property value
Settings.Secure.putInt(mContentResolver, Settings.Secure.ADB_ENABLED,
"1".equals(SystemProperties.get("persist.service.adb.enable")) ? 1 : 0);
// register observer to listen for settings changes
mContentResolver.registerContentObserver(Settings.Secure.getUriFor(Settings.Secure.ADB_ENABLED),
false, new AdbSettingsObserver());
// Before things start rolling, be sure we have decided whether
// we are in safe mode.
final boolean safeMode = wm.detectSafeMode();
if (safeMode) {
try {
ActivityManagerNative.getDefault().enterSafeMode();
// Post the safe mode state in the Zygote class
Zygote.systemInSafeMode = true;
// Disable the JIT for the system_server process
VMRuntime.getRuntime().disableJitCompilation();
} catch (RemoteException e) {
}
} else {
// Enable the JIT for the system_server process
VMRuntime.getRuntime().startJitCompilation();
}
// It is now time to start up the app processes...
if (devicePolicy != null) {
devicePolicy.systemReady();
}
if (notification != null) {
notification.systemReady();
}
if (statusBar != null) {
statusBar.systemReady();
}
wm.systemReady();
power.systemReady();
try {
pm.systemReady();
} catch (RemoteException e) {
}
// These are needed to propagate to the runnable below.
final BatteryService batteryF = battery;
final ConnectivityService connectivityF = connectivity;
final DockObserver dockF = dock;
final ThrottleService throttleF = throttle;
final UiModeManagerService uiModeF = uiMode;
final AppWidgetService appWidgetF = appWidget;
final WallpaperManagerService wallpaperF = wallpaper;
final InputMethodManagerService immF = imm;
final RecognitionManagerService recognitionF = recognition;
final LocationManagerService locationF = location;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
((ActivityManagerService)ActivityManagerNative.getDefault())
.systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
if (batteryF != null) batteryF.systemReady();
if (connectivityF != null) connectivityF.systemReady();
if (dockF != null) dockF.systemReady();
if (uiModeF != null) uiModeF.systemReady();
if (recognitionF != null) recognitionF.systemReady();
Watchdog.getInstance().start();
// It is now okay to let the various system services start their
// third party code...
if (appWidgetF != null) appWidgetF.systemReady(safeMode);
if (wallpaperF != null) wallpaperF.systemReady();
if (immF != null) immF.systemReady();
if (locationF != null) locationF.systemReady();
if (throttleF != null) throttleF.systemReady();
}
});
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}

代码虽然有点长,但是其实非常简单,主要就是各Java服务的注册。同本地系统服务一样,Java系统服务必须先把相关服务注册到Context Manager中,其他模块才能使用这些服务。但是Java系统服务的注册方式与基于C++的本地系统服务不同,它通过调用ServiceManager类的addService()静态方法,将自身注册到Context Manager中。

到这里,我们可以归纳出Android Framework的启动过程:

SystemServer

上面这个图也大致描述出了Android系统的启动过程。下一篇博客中我们将介绍SystemServer是如何处理来自所绑定的socket的请求从而运行新的应用程序的。