Framework学习(三)SystemServer进程
一、概述
SystemServer是Android系统的核心之一,大部分Android提供的服务都运行在这个进程里,SystemServer中运行的服务总共有60多种。为了防止应用进程对系统造成破坏,Android的应用进程没有权限直接访问设备的底层资源,只能通过SystemService中的代理访问。通过Binder,用户进程在使用SystemService中的服务并没有太多不便变之处。
上一节已经讲到ZygoteInit的启动,那么ZygoteInit是如何启动SystemServer的呢
二、fork过程
时序图
代码解析
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) { ...//5、fork一个SystemServer进程 if (startSystemServer) { Runnable r = forkSystemServer(abiList, socketName, zygoteServer); if (r != null) { r.run(); return; } } ...}
ZygoteInit#forkSystemServer()
620 private static Runnable forkSystemServer(String abiList, String socketName,621 ZygoteServer zygoteServer) { ...640 /* 硬编码指令行,用于启动SystemServer */641 String args[] = { 642 "--setuid=1000",643 "--setgid=1000",644 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",645 "--capabilities=" + capabilities + "," + capabilities,646 "--nice-name=system_server",647 "--runtime-args",648 "com.android.server.SystemServer",649 };650 ZygoteConnection.Arguments parsedArgs = null;651652 int pid;653654 try { 655 parsedArgs = new ZygoteConnection.Arguments(args);656 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);657 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);658659 /* 请求fork SystemServer进程 */660 pid = Zygote.forkSystemServer(661 parsedArgs.uid, parsedArgs.gid,662 parsedArgs.gids,663 parsedArgs.debugFlags,664 null,665 parsedArgs.permittedCapabilities,666 parsedArgs.effectiveCapabilities);667 } catch (IllegalArgumentException ex) { 668 throw new RuntimeException(ex);669 }670671 /* pid为0表示子进程,即SystemServer进程 */672 if (pid == 0) { 673 if (hasSecondZygote(abiList)) { 674 waitForSecondaryZygote(socketName);675 }676677 zygoteServer.closeServerSocket();678 return handleSystemServerProcess(parsedArgs);679 }680681 return null;682 }
ZygoteInit#handleSystemServerProcess()
452 private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) { ...456 if (parsedArgs.niceName != null) { 457 Process.setArgV0(parsedArgs.niceName);//进程名为参数里的niceName:system_server458 } ...482 if (parsedArgs.invokeWith != null) { //注1483 String[] args = parsedArgs.remainingArgs;484 // If we have a non-null system server class path, we'll have to duplicate the485 // existing arguments and append the classpath to it. ART will handle the classpath486 // correctly when we exec a new process.487 if (systemServerClasspath != null) { 488 String[] amendedArgs = new String[args.length + 2];489 amendedArgs[0] = "-cp";490 amendedArgs[1] = systemServerClasspath;491 System.arraycopy(args, 0, amendedArgs, 2, args.length);492 args = amendedArgs;493 }494495 WrapperInit.execApplication(parsedArgs.invokeWith,496 parsedArgs.niceName, parsedArgs.targetSdkVersion,497 VMRuntime.getCurrentInstructionSet(), null, args);498499 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");500 } else { 501 ClassLoader cl = null;502 if (systemServerClasspath != null) { 503 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);504505 Thread.currentThread().setContextClassLoader(cl);506 }507508 /*509 * Pass the remaining arguments to SystemServer.510 */511 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);512 }513514 /* should never reach here */515 }
注:1、parsedArgs.invokeWith属性默认为null,通过调用ZygoteInit.zygoteInit来进一步启动SystemServer。
ZygoteInit#zygoteInit()
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { 852 if (RuntimeInit.DEBUG) { 853 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");854 }855856 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");857 RuntimeInit.redirectLogStreams();858 //初始化运行环境859 RuntimeInit.commonInit(); //调用Native层的代码,启动Binder线程池860 ZygoteInit.nativeZygoteInit(); //调用程序入口函数861 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);862
nativeZygoteInit函数对应的JNI文件为AndroidRuntime.cpp
/frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)223{ 224 gCurRuntime->onZygoteInit();225}int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)250{ 251 const JNINativeMethod methods[] = { 252 { "nativeZygoteInit", "()V",253 (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },254 };255 return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",256 methods, NELEM(methods));257}
通过代码可以看到,实际调用的函数是onZygoteInit()
/frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()92 { 93 sp<ProcessState> proc = ProcessState::self();94 ALOGV("App process: starting thread pool.\n");95 proc->startThreadPool();96 }
/frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::startThreadPool()152{ 153 AutoMutex _l(mLock);154 if (!mThreadPoolStarted) { 155 mThreadPoolStarted = true;156 spawnPooledThread(true);157 }158}
注:支持Binder通信的进程中都有一个ProcessState类,它里面有一个mThreadPoolStarted 变量,来表示Binder线程池是否已经被启动过,默认值为false。在每次调用这个函数时都会先去检查这个标记,从而确保Binder线程池只会被启动一次。
ProcessState#spawnPooledThread()
void ProcessState::spawnPooledThread(bool isMain)347{ 348 if (mThreadPoolStarted) { 349 String8 name = makeBinderThreadName();350 ALOGV("Spawning new pooled thread, name=%s\n", name.string());351 sp<Thread> t = new PoolThread(isMain);352 t->run(name.string());//注1353 }354}
注:1、调用PoolThread的run函数来启动一个新的线程
ProcessState#PoolThread
class PoolThread : public Thread51{ 52public:53 explicit PoolThread(bool isMain)54 : mIsMain(isMain)55 { 56 }5758protected:59 virtual bool threadLoop()60 { 61 IPCThreadState::self()->joinThreadPool(mIsMain);//注162 return false;63 }6465 const bool mIsMain;66};
注:1、PoolThread类继承了Thread类。注释1处会将调用IPCThreadState的joinThreadPool函数,将当前线程注册到Binder驱动程序中,这样我们创建的线程就加入了Binder线程池中,这样新创建的SyetemServer进程就支持Binder进程间通信了。
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,291 ClassLoader classLoader) { 292 // If the application calls System.exit(), terminate the process293 // immediately without running any shutdown hooks. It is not possible to294 // shutdown an Android application gracefully. Among other things, the295 // Android runtime shutdown hooks close the Binder driver, which can cause296 // leftover running threads to crash before the process actually exits.297 nativeSetExitWithoutCleanup(true); //虚拟机环境设置301 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);302 VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);303304 final Arguments args = new Arguments(argv);305306 // The end of of the RuntimeInit event (see #zygoteInit).307 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);308309 // Remaining arguments are passed to the start class's static main310 return findStaticMain(args.startClass, args.startArgs, classLoader);311 }
RuntimeInit#findStaticMain()
private static Runnable findStaticMain(String className, String[] argv,233 ClassLoader classLoader) { 234 Class<?> cl;235236 try { 237 cl = Class.forName(className, true, classLoader);//注1238 } catch (ClassNotFoundException ex) { 239 throw new RuntimeException(240 "Missing class when invoking static main " + className,241 ex);242 }243244 Method m;245 try { // 获取main方法246 m = cl.getMethod("main", new Class[] { String[].class });247 } catch (NoSuchMethodException ex) { 248 throw new RuntimeException(249 "Missing static main on " + className, ex);250 } catch (SecurityException ex) { 251 throw new RuntimeException(252 "Problem getting static main on " + className, ex);253 }254 // 判断修饰符,须是static且是public类型255 int modifiers = m.getModifiers();256 if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { 257 throw new RuntimeException(258 "Main method is not public and static on " + className);259 }260261 /*262 * This throw gets caught in ZygoteInit.main(), which responds263 * by invoking the exception's run() method. This arrangement264 * clears up all the stack frames that were required in setting265 * up the process.266 */267 return new MethodAndArgsCaller(m, argv);//注2268 }
注:1、传入的className就是com.android.server.SystemServer ,因此通过反射返回的cl为SystemServer类。
2、将找到的main函数传入到MethodAndArgsCaller并返回。这个会在ZygoteInit中forkSystemServer之后执行run函数。
RuntimeInit#MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable { 425 /** method to call */426 private final Method mMethod;427428 /** argument array */429 private final String[] mArgs;430431 public MethodAndArgsCaller(Method method, String[] args) { 432 mMethod = method;433 mArgs = args;434 }435436 public void run() { 437 try { //注1438 mMethod.invoke(null, new Object[] { mArgs });439 } catch (IllegalAccessException ex) { 440 throw new RuntimeException(ex);441 } catch (InvocationTargetException ex) { 442 Throwable cause = ex.getCause();443 if (cause instanceof RuntimeException) { 444 throw (RuntimeException) cause;445 } else if (cause instanceof Error) { 446 throw (Error) cause;447 }448 throw new RuntimeException(ex);449 }450 }451 }452}
注:1、通过反射调用了com.android.server.SystemServer#main(String[] args)。至此,Zygote进程fork出SystemServer进程,并成功调用SystemServer#main()
三、运行过程
SystemServer的运行比较清晰,此处就不画时序图了。
主要做了几件事:
- 调用createSystemContext()来创建系统上下文
- 创建SystemServiceManager
- 启动各种服务
源码解析
/frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) { 267 new SystemServer().run();268 }private void run() { 278 try { 279 traceBeginAndSlog("InitBeforeStartServices");280 //设置系统时钟最早为1970,早于1970很多api无法正常工作284 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { 285 Slog.w(TAG, "System clock is before 1970; setting to 1970.");286 SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);287 } // 默认时区GMT.292 String timezoneProperty = SystemProperties.get("persist.sys.timezone");293 if (timezoneProperty == null || timezoneProperty.isEmpty()) { 294 Slog.w(TAG, "Timezone not set; setting to GMT.");295 SystemProperties.set("persist.sys.timezone", "GMT");296 } ...366 //注1367 System.loadLibrary("android_servers"); // 初始化系统上下文374 createSystemContext(); ...376 // 创建SystemServiceManager.377 mSystemServiceManager = new SystemServiceManager(mSystemContext);378 mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);379 LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);380 // Prepare the thread pool for init tasks that can be parallelized381 SystemServerInitThreadPool.get();382 } finally { 383 traceEnd(); // InitBeforeStartServices384 }385386 // 启动各种系统服务.387 try { 388 traceBeginAndSlog("StartServices");389 startBootstrapServices();390 startCoreServices();391 startOtherServices();392 SystemServerInitThreadPool.shutdown();393 } catch (Throwable ex) { 394 Slog.e("System", "******************************************");395 Slog.e("System", "************ Failure starting system services", ex);396 throw ex;397 } finally { 398 traceEnd();399 } ...414415 // Loop forever.416 Looper.loop();417 throw new RuntimeException("Main thread loop unexpectedly exited");418 }
注:1、加载“android_servers.so”库,该库包含源码在frameworks/base/services/目录下
1、初始化系统上下文
/frameworks/base/services/java/com/android/server/SystemServer.java
private void createSystemContext() { // 进行ActivityThread初始化484 ActivityThread activityThread = ActivityThread.systemMain(); // 获取系统上下文485 mSystemContext = activityThread.getSystemContext();486 mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);487488 final Context systemUiContext = activityThread.getSystemUiContext();489 systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);490 }
/frameworks/base/core/java/android/app/ActivityThread.java
public static ActivityThread systemMain() { 6399 // The system process on low-memory devices do not get to use hardware6400 // accelerated drawing, since this can add too much overhead to the6401 // process.6402 if (!ActivityManager.isHighEndGfx()) { 6403 ThreadedRenderer.disable(true);6404 } else { 6405 ThreadedRenderer.enableForegroundTrimming();6406 }6407 ActivityThread thread = new ActivityThread();6408 thread.attach(true);6409 return thread;6410 }
注:创建了了一个ActivityThread对象。然后调用attach(boolean)方法来进行初始化,ActivityThread是一个Application的主线程类,(记住,它不是Thread,因为它既没有继承Thread,也没有实现Runnable)
ActivityThread创建实例会创建ApplicationThread对象(用于基于的BinderIPC通信)、H对象mH,以及主线的Looper对象mLooper。
/frameworks/base/core/java/android/app/ActivityThread.java
private void attach(boolean system) { 6316 sCurrentActivityThread = this; //system为true,即该进程为系统进程6317 mSystemThread = system;6318 if (!system) { 6319 ViewRootImpl.addFirstDrawHandler(new Runnable() { 6320 @Override6321 public void run() { // 检查jit能否用,6.0即ART,不用jit, // 不过由于向下兼容,所以这里还有检查jit6322 ensureJitEnabled();6323 }6324 });6325 android.ddm.DdmHandleAppName.setAppName("" ,6326 UserHandle.myUserId());6327 RuntimeInit.setApplicationObject(mAppThread.asBinder());6328 final IActivityManager mgr = ActivityManager.getService();6329 try { 6330 mgr.attachApplication(mAppThread);6331 } catch (RemoteException ex) { 6332 throw ex.rethrowFromSystemServer();6333 }6334 // 添加GC观察者6335 BinderInternal.addGcWatcher(new Runnable() { 6336 @Override public void run() { 6337 if (!mSomeActivitiesChanged) { 6338 return;6339 }6340 Runtime runtime = Runtime.getRuntime();6341 long dalvikMax = runtime.maxMemory();6342 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();6343 if (dalvikUsed > ((3*dalvikMax)/4)) { 6344 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)6345 + " total=" + (runtime.totalMemory()/1024)6346 + " used=" + (dalvikUsed/1024));6347 mSomeActivitiesChanged = false;6348 try { 6349 mgr.releaseSomeActivities(mAppThread);6350 } catch (RemoteException e) { 6351 throw e.rethrowFromSystemServer();6352 }6353 }6354 }6355 });6356 } else { 6357 // Don't set application object here -- if the system crashes,6358 // we can't display an alert, we just want to die die die.//设置Java Application 在DDM里面的名称 即 system_process6359 android.ddm.DdmHandleAppName.setAppName("system_process",6360 UserHandle.myUserId());6361 try { // 创建 系统应用的Instrumentation对象6362 mInstrumentation = new Instrumentation(); // 创建 ContextImpl对象6363 ContextImpl context = ContextImpl.createAppContext(6364 this, getSystemContext().mPackageInfo); // 创建系统进程的Application对象6365 mInitialApplication = context.mPackageInfo.makeApplication(true, null);// 调用系统进程的onCreate()方法6366 mInitialApplication.onCreate();6367 } catch (Exception e) { 6368 throw new RuntimeException(6369 "Unable to instantiate Application():" + e.toString(), e);6370 }6371 }63726373 // add dropbox logging to libcore6374 DropBox.setReporter(new DropBoxReporter());63756376 ViewRootImpl.ConfigChangedCallback configChangedCallback6377 = (Configuration globalConfig) -> { 6378 synchronized (mResourcesManager) { 6379 // We need to apply this change to the resources immediately, because upon returning6380 // the view hierarchy will be informed about it.6381 if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,6382 null /* compat */)) { 6383 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),6384 mResourcesManager.getConfiguration().getLocales());63856386 // This actually changed the resources! Tell everyone about it.6387 if (mPendingConfiguration == null6388 || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { 6389 mPendingConfiguration = globalConfig;6390 sendMessage(H.CONFIGURATION_CHANGED, globalConfig);6391 }6392 }6393 }6394 };6395 ViewRootImpl.addConfigCallback(configChangedCallback);6396 }
attach的主要作用:
- 创建Instrumentation对象
- 通过调用ContextImpl.createAppContext方法来创建ContextImpl对象
- 通过调用context.mPackageInfo.makeApplication创建mInitialApplication对象
- 调用mInitialApplication对象的onCreate()
所以,attach方法在参数system为true的时候,会创建一个类似的Application的环境。
这就是为什么在SystemServer中要创建ActivityThread的原因了,因为SystemServer不仅仅是一个后台进程,同时它还是一个运行着组件的Service进程,很多系统的对话框就是从SystemServer中显示出来的,因此,SystemServer本身也需要一个和APK应用类似的上下文环境。
/frameworks/base/core/java/android/app/LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass,960 Instrumentation instrumentation) { 961 if (mApplication != null) { 962 return mApplication;963 }964965 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");966967 Application app = null;968969 String appClass = mApplicationInfo.className;970 if (forceDefaultAppClass || (appClass == null)) { 971 appClass = "android.app.Application";972 }973974 try { 975 java.lang.ClassLoader cl = getClassLoader();976 if (!mPackageName.equals("android")) { 977 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,978 "initializeJavaContextClassLoader");979 initializeJavaContextClassLoader();980 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);981 }982 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); // 创建Application对象983 app = mActivityThread.mInstrumentation.newApplication(984 cl, appClass, appContext);985 appContext.setOuterContext(app);986 } catch (Exception e) { 987 if (!mActivityThread.mInstrumentation.onException(app, e)) { 988 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);989 throw new RuntimeException(990 "Unable to instantiate application " + appClass991 + ": " + e.toString(), e);992 }993 }994 mActivityThread.mAllApplications.add(app);995 mApplication = app;996997 if (instrumentation != null) { 998 try { // 利用instrumentation调用Application的onCreate方法999 instrumentation.callApplicationOnCreate(app);1000 } catch (Exception e) { 1001 if (!instrumentation.onException(app, e)) { 1002 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);1003 throw new RuntimeException(1004 "Unable to create application " + app.getClass().getName()1005 + ": " + e.toString(), e);1006 }1007 }1008 }10091010 // Rewrite the R 'constants' for all library apks.1011 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();1012 final int N = packageIdentifiers.size();1013 for (int i = 0; i < N; i++) { 1014 final int id = packageIdentifiers.keyAt(i);1015 if (id == 0x01 || id == 0x7f) { 1016 continue;1017 }10181019 rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);1020 }10211022 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);10231024 return app;1025 }
/frameworks/base/core/java/android/app/ActivityThread.java
public ContextImpl getSystemContext() { 2154 synchronized (this) { 2155 if (mSystemContext == null) { 2156 mSystemContext = ContextImpl.createSystemContext(this);2157 }2158 return mSystemContext;2159 }2160 }
/frameworks/base/core/java/android/app/ContextImpl.java
static ContextImpl createSystemContext(ActivityThread mainThread) { 2244 LoadedApk packageInfo = new LoadedApk(mainThread);2245 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,2246 null);2247 context.setResources(packageInfo.getResources());2248 context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),2249 context.mResourcesManager.getDisplayMetrics());2250 return context;2251 }
/frameworks/base/core/java/android/app/LoadedApk.java
LoadedApk(ActivityThread activityThread) { 185 mActivityThread = activityThread;186 mApplicationInfo = new ApplicationInfo();187 mApplicationInfo.packageName = "android";188 mPackageName = "android";189 mAppDir = null;190 mResDir = null;191 mSplitAppDirs = null;192 mSplitResDirs = null;193 mSplitClassLoaderNames = null;194 mOverlayDirs = null;195 mDataDir = null;196 mDataDirFile = null;197 mDeviceProtectedDataDirFile = null;198 mCredentialProtectedDataDirFile = null;199 mLibDir = null;200 mBaseClassLoader = null;201 mSecurityViolation = false;202 mIncludeCode = true;203 mRegisterPackage = false;204 mClassLoader = ClassLoader.getSystemClassLoader();205 mResources = Resources.getSystem();206 }
注:LoadApk对象用来保存一个apk信息,这个构造方法中会将使用的包名指定为"android"
/frameworks/base/core/java/android/app/ContextImpl.java
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,2324 @NonNull LoadedApk packageInfo, @Nullable String splitName,2325 @Nullable IBinder activityToken, @Nullable UserHandle user, int flags,2326 @Nullable ClassLoader classLoader) { 2327 mOuterContext = this;23282329 // If creator didn't specify which storage to use, use the default2330 // location for application.2331 if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE2332 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) { 2333 final File dataDir = packageInfo.getDataDirFile();2334 if (Objects.equals(dataDir, packageInfo.getCredentialProtectedDataDirFile())) { 2335 flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;2336 } else if (Objects.equals(dataDir, packageInfo.getDeviceProtectedDataDirFile())) { 2337 flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE;2338 }2339 }23402341 mMainThread = mainThread;2342 mActivityToken = activityToken;2343 mFlags = flags;23442345 if (user == null) { 2346 user = Process.myUserHandle();2347 }2348 mUser = user;23492350 mPackageInfo = packageInfo;2351 mSplitName = splitName;2352 mClassLoader = classLoader;2353 mResourcesManager = ResourcesManager.getInstance();23542355 if (container != null) { 2356 mBasePackageName = container.mBasePackageName;2357 mOpPackageName = container.mOpPackageName;2358 setResources(container.mResources);2359 mDisplay = container.mDisplay;2360 } else { 2361 mBasePackageName = packageInfo.mPackageName;2362 ApplicationInfo ainfo = packageInfo.getApplicationInfo();2363 if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) { 2364 // Special case: system components allow themselves to be loaded in to other2365 // processes. For purposes of app ops, we must then consider the context as2366 // belonging to the package of this process, not the system itself, otherwise2367 // the package+uid verifications in app ops will fail.2368 mOpPackageName = ActivityThread.currentPackageName();2369 } else { 2370 mOpPackageName = mBasePackageName;2371 }2372 }23732374 mContentResolver = new ApplicationContentResolver(this, mainThread, user);2375 }
在ContextImpl的构造方法中会初始化该进程的各个字段,例如资源、包信息、屏幕配置等。
2、创建SystemServiceManager
/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
SystemServiceManager(Context context) { 49 mContext = context;50 }
/frameworks/base/core/java/com/android/server/LocalServices.java
public static <T> void addService(Class<T> type, T service) { 55 synchronized (sLocalServiceObjects) { 56 if (sLocalServiceObjects.containsKey(type)) { 57 throw new IllegalStateException("Overriding service registration");58 }59 sLocalServiceObjects.put(type, service);60 }61 }
addService函数把SystemServiceManager放到LocalServicesd的sLocalServiceObjects中,其中sLocalServiceObjects是一个ArrayMap。
3、启动各种服务
startBootstrapServices()
引导服务 | 作用 |
---|---|
Installer | 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务 |
ActivityManagerService | 负责四大组件的启动、切换、调度。 |
PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |
LightsService | 管理和显示背光LED |
DisplayManagerService | 用来管理所有显示设备 |
UserManagerService | 多用户模式管理 |
SensorService | 为系统提供各种感应器服务 |
PackageManagerService | 用来对apk进行安装、解析、删除、卸载等等操作 |
startCoreServices()
核心服务 | 作用 |
---|---|
BatteryService | 管理电池相关的服务 |
UsageStatsService | 收集用户使用每一个APP的频率、使用时常 |
WebViewUpdateService | WebView更新服务 |
startOtherServices()
其他服务 | 作用 |
---|---|
CameraService | 摄像头相关服务 |
AlarmManagerService | 全局定时器管理服务 |
InputManagerService | 管理输入事件 |
WindowManagerService | 窗口管理服务 |
VrManagerService | VR模式管理服务 |
BluetoothService | 蓝牙管理服务 |
NotificationManagerService | 通知管理服务 |
DeviceStorageMonitorService | 存储相关管理服务 |
LocationManagerService | 定位管理服务 |
AudioService | 音频相关管理服务 |
… | … |
启动服务的两种方式
先观察startBootstrapServices()的代码
private void startBootstrapServices() { ...531 traceBeginAndSlog("StartPowerManager");532 mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);533 traceEnd(); ...566 mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); ...585 mPackageManagerService = PackageManagerService.main(mSystemContext, installer,586 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);587 mFirstBoot = mPackageManagerService.isFirstBoot();588 mPackageManager = mSystemContext.getPackageManager();589 traceEnd(); ...646}
以PowerManagerService的启动为例,执行startService方法,之后进过一段时间,会调用startBootPhase方法。
public <T extends SystemService> T startService(Class<T> serviceClass) { 83 try { 84 final String name = serviceClass.getName();85 Slog.i(TAG, "Starting " + name);86 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);8788 // Create the service.89 if (!SystemService.class.isAssignableFrom(serviceClass)) { 90 throw new RuntimeException("Failed to create " + name91 + ": service must extend " + SystemService.class.getName());92 }93 final T service;94 try { 95 Constructor<T> constructor = serviceClass.getConstructor(Context.class);96 service = constructor.newInstance(mContext);97 } catch (InstantiationException ex) { 98 throw new RuntimeException("Failed to create service " + name99 + ": service could not be instantiated", ex);100 } catch (IllegalAccessException ex) { 101 throw new RuntimeException("Failed to create service " + name102 + ": service must have a public constructor with a Context argument", ex);103 } catch (NoSuchMethodException ex) { 104 throw new RuntimeException("Failed to create service " + name105 + ": service must have a public constructor with a Context argument", ex);106 } catch (InvocationTargetException ex) { 107 throw new RuntimeException("Failed to create service " + name108 + ": service constructor threw an exception", ex);109 }110111 startService(service);112 return service;113 } finally { 114 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);115 }116 }117118 public void startService(@NonNull final SystemService service) { 119 // Register it.120 mServices.add(service);121 // Start it.122 long time = SystemClock.elapsedRealtime();123 try { 124 service.onStart();125 } catch (RuntimeException ex) { 126 throw new RuntimeException("Failed to start service " + service.getClass().getName()127 + ": onStart threw an exception", ex);128 }129 warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");130 }
启动服务实际调用了对应服务的onStart方法。
而PackageManagerService执行的却是PackageManagerService的main方法。
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public static PackageManagerService main(Context context, Installer installer,2311 boolean factoryTest, boolean onlyCore) { 2312 // Self-check for initial settings.2313 PackageManagerServiceCompilerMapping.checkProperties();23142315 PackageManagerService m = new PackageManagerService(context, installer,2316 factoryTest, onlyCore);2317 m.enableSystemUserPackages();2318 ServiceManager.addService("package", m);2319 final PackageManagerNative pmn = m.new PackageManagerNative();2320 ServiceManager.addService("package_native", pmn);2321 return m;2322 }
由代码可见,这里以addService的方法添加到ServiceManager中去。
那么为什么执行startBootPhase又是为什么呢?
public void startBootPhase(final int phase) { 139 if (phase <= mCurrentPhase) { 140 throw new IllegalArgumentException("Next phase must be larger than previous");141 }142 mCurrentPhase = phase;143144 Slog.i(TAG, "Starting phase " + mCurrentPhase);145 try { 146 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase);147 final int serviceLen = mServices.size(); //遍历服务执行onBootPhase方法148 for (int i = 0; i < serviceLen; i++) { 149 final SystemService service = mServices.get(i);150 long time = SystemClock.elapsedRealtime();151 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName());152 try { 153 service.onBootPhase(mCurrentPhase);154 } catch (Exception ex) { 155 throw new RuntimeException("Failed to boot service "156 + service.getClass().getName()157 + ": onBootPhase threw an exception during phase "158 + mCurrentPhase, ex);159 }160 warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase");161 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);162 }163 } finally { 164 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);165 }166 }
代码可见,会遍历所有向SystemServiceManager注册过的service的onBootPhase()方法
查看SystemService类,可见系统服务有多个阶段。
/frameworks/base/services/core/java/com/android/server/SystemService.java
public abstract class SystemService { 48 /*49 * Boot Phases50 */51 public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?5253 /**54 * After receiving this boot phase, services can obtain lock settings data.55 */56 public static final int PHASE_LOCK_SETTINGS_READY = 480;5758 /**59 * After receiving this boot phase, services can safely call into core system services60 * such as the PowerManager or PackageManager.61 */62 public static final int PHASE_SYSTEM_SERVICES_READY = 500;6364 /**65 * After receiving this boot phase, services can broadcast Intents.66 */67 public static final int PHASE_ACTIVITY_MANAGER_READY = 550;6869 /**70 * After receiving this boot phase, services can start/bind to third party apps.71 * Apps will be able to make Binder calls into services at this point.72 */73 public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;7475 /**76 * After receiving this boot phase, services can allow user interaction with the device.77 * This phase occurs when boot has completed and the home application has started.78 * System services may prefer to listen to this phase rather than registering a79 * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.80 */81 public static final int PHASE_BOOT_COMPLETED = 1000; ..... 120 /**121 * Called on each phase of the boot process. Phases before the service's start phase122 * (as defined in the @Service annotation) are never received.123 *124 * @param phase The current boot phase.125 */126 public void onBootPhase(int phase) { } ....}
SystemServer会依次启动许多服务,但服务之间的功能是相互依赖的。因此,每个服务刚被启动的时候,都必须完成最基本的初始化。所以当系统运动到某个阶段时,调用SystemServiceManager的startBootPhase,这样所有的服务都可以进一步完成换这个阶段可以进行的初始化工作。
通过这个方式,每个服务的初始化过程可以按阶段分为好几个部分,增加了不同阶段的初始化工作的清晰度;同时,每个阶段调用startBootPhase函数,就像一种同步机制一样,让所有服务的初始化进程保持一致的步调。
总结一下启动服务的两种方式:
- startService()。主要功能:创建serviceClass的对象,将刚创建的对象添加到SystemServiceManager的成员变量mServices,再调用刚创建对象的onStart()方法。对于服务启动到一定阶段,进入相应的Phase时,会调用SystemServiceManager的startBootPhase()方法完成初始化
- addService()。该方法用于初始化继承于IBinder的服务。主要功能将服务向Native层的ServiceManager注册服务。
更多相关文章
- [置顶] Android中AIDL实现进程通信(附源码下载)
- 关于做Android+J2ee系统集成开发的一点心得来源
- 安卓MonkeyRunner源码分析之与Android设备通讯方式
- Android日志系统驱动程序Logger源代码分析
- android manifest 文件Activity配置节中的属性汇总
- Android面试题 -
- android app内置webview,随android版本升级进程关系的变化
- 为什么ios比android流畅
- Android(安卓)& Chrome