一、引言 在分析Android系统架构的文章中,我们只是静态分析了Android系统架构,虽然可以了解Android架构地层次和功能,但不足以了解Android整个系统运行时各层次之间的信息传递和交互,即不能真正看穿Android的运行机理,故还需进一步学习。
所以新开一篇文章结合Android 8.0源码来讲述Android系统启动流程。
二、Android系统启动流程 这是一张Android系统启动的流程图(来自gityuan)。
根据上图,整个过程可分为以下几个阶段:
Boot Loader阶段 :设备加电后,首先运行的是Boot Loader程序。Boot Loader主要负责硬件初始化和设备的引导操作。
Kernel阶段 :当Boot Loader完成初始化操作后,它会将控制权交给内核。内核是Android系统的核心组件,负责管理系统资源、调度进程等。在这个阶段,内核会加载文件系统和驱动程序,为最终系统的启动做好准备。
Init进程阶段 :在Kernel阶段完成后,Init进程就会被启动。Init进程是用户空间的第一个进程,负责启动系统中其他所有的进程。在这个阶段,Init进程会依次执行init.rc脚本中定义的各项任务,包括挂载文件系统、启动服务等。
Zygote进程阶段 :在Init进程启动完成后,Android系统会创建一个名为Zygote的进程,他是所有Java应用程序的孵化器。Zygote进程会预加载大量的Java类和资源,以提高应用程序的启动速度。当用户启动新的应用程序时,Zygote进程会复制自身并生成新的虚拟机实例,然后加载对应应用程序的代码并执行。
System Server阶段 :在Zygote进程启动完成后,System Server进程就会被启动。System Server是整个Android系统中非常重要的一个进程,负责启动并管理多种系统服务,例如Activity Manager、Window Manager、PackageManager等。在这个阶段,用户才可以看到开始界面,开始使用手机。
Launcher启动阶段 :在System Server启动完成后,系统会开始启动Android应用程序。在这个阶段,启动器会展示所有已安装的应用程序,用户可以选择启动所需应用程序。
2.1 Boot Loader阶段 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM 里的预设代码开始执行,将引导程序(Boot Loader)加载到 RAM中并执行,主要任务是将操作系统加载到内存中并建立好操作系统运行的环境,然后将控制权转移到操作系统内核。
2.2 Kernel阶段 Kernel阶段会启动Kernel的swapper进程(pid=0),该进程又称为idle进程,是Kernel开创的第一个进程,用于初始化进程管理、内存管理,加载驱动等相关工作,以及启动kthreadd进程(pid=2),该进程是Linux系统的内核进程,是所有内核进程的鼻祖,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。Kernel完成这些工作后,会在系统文件中寻找init.rc文件,并启动init进程。
2.3 Init进程阶段 init
进程(pid=1)是Android
系统中用户空间的第一个进程,是所有用户进程的鼻祖。init源码在system/core/init/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 int main (int argc, char ** argv) { ...... add_environment ("PATH" , _PATH_DEFPATH); ...... if (is_first_stage) { ...... mount ("tmpfs" , "/dev" , "tmpfs" , MS_NOSUID, "mode=0755" ); ...... InitKernelLogging (argv); ...... } ...... property_init (); ...... signal_handler_init (); ...... start_property_service (); ...... if (bootscript.empty ()) { parser.ParseConfig ("/init.rc" ); ...... } else { ...... } ...... while (true ) { } return 0 ; }
而在解析init.rc
(system/core/rootdir/init.rc
)过程中会孵化zygote
进程。
从代码中可以看出init
进程阶段主要做了以下事情:
创建和挂载启动所需要的文件目录
初始化和启动属性服务
解析init.rc
配置文件并孵化zygote
进程
2.4 Zygote进程阶段 在Android
系统中,DVM
和ART
、应用程序进程以及运行系统的关键服务的SystemServer
进程都是由Zygote
进程创建的,我们也将它称为孵化器。它通过fork(复制进程)来创建应用进程和SystemServer
进程 ,由于Zygote
进程在启动时会创建DVM
或者ART
,因此通过fork而创建的应用程序进程和SystemServer
进程可以在内部获取一个DVM
或者ART
的实例副本。
通过解析init.rc
配置文件可以知道init
启动Zygote
时主要是调用app_main.cpp
的main
方法(之后再分析),所在路径为frameworks/base/cmds/app_process/app_main.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 int main (int argc, char * const argv[]) { ...... while (i < argc) { const char * arg = argv[i++]; if (strcmp (arg, "--zygote" ) == 0 ) { zygote = true ; niceName = ZYGOTE_NICE_NAME; } else if (strcmp (arg, "--start-system-server" ) == 0 ) { startSystemServer = true ; } else if (strcmp (arg, "--application" ) == 0 ) { application = true ; } else if (strncmp (arg, "--nice-name=" , 12 ) == 0 ) { niceName.setTo (arg + 12 ); } else if (strncmp (arg, "--" , 2 ) != 0 ) { className.setTo (arg); break ; } else { --i; break ; } } ...... if (zygote) { runtime.start ("com.android.internal.os.ZygoteInit" , args, zygote); } else if (className) { runtime.start ("com.android.internal.os.RuntimeInit" , args, zygote); } else { fprintf (stderr, "Error: no class name or --zygote supplied.\n" ); app_usage (); LOG_ALWAYS_FATAL ("app_process: no class name or --zygote supplied." ); } }
zygote
进程都是通过fork自身来创建子进程的,这样Zygote
进程以及它的子进程都可以进入app_main.cpp
的main
函数,因此为了区分main
函数运行在哪个进程中,对argc
进行了判断。
接下来查看runtime.start()
这个方法,这个方法属于AppRuntime
类,而这个类又继承AndroidRuntime
,路径为/frameworks/base/core/jni/AndroidRuntime.cpp
,位于第994行。
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 void AndroidRuntime::start (const char * className, const Vector<String8>& options, bool zygote) { ...... JniInvocation jni_invocation; jni_invocation.Init (NULL ); JNIEnv* env; if (startVm (&mJavaVM, &env, zygote) != 0 ) { return ; } onVmCreated (env); if (startReg (env) < 0 ) { ALOGE ("Unable to register all android natives\n" ); return ; } ...... classNameStr = env->NewStringUTF (className); ...... char * slashClassName = toSlashClassName (className); jclass startClass = env->FindClass (slashClassName); if (startClass == NULL ) { ALOGE ("JavaVM unable to locate class '%s'\n" , slashClassName); } else { jmethodID startMeth = env->GetStaticMethodID (startClass, "main" , "([Ljava/lang/String;)V" ); if (startMeth == NULL ) { ALOGE ("JavaVM unable to find main() in '%s'\n" , className); } else { env->CallStaticVoidMethod (startClass, startMeth, strArray); ...... }
首先通过startVm
方法创建java虚拟机,然后通过startReg
方法为Java虚拟机注册JNI
方法,将className
转成路径后,即找到ZygoteInit
类所在位置,然后通过GetStaticMethodID
获取main
方法,最后通过CallStaticVoidMethod
方法启动ZygoteInit
。
值得注意的是,这里是通过JNI
调用ZygoteInit
的main
方法,查看ZygoteInit
也可以发现是java语言编写的。当前Zygote
的运行逻辑在Native
层中,通过JNI
调用java代码后,Zygote
就进入到了java框架层!
继续查看ZygoteInit
,所在位置为frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
。
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 public static void main (String argv[]) { ...... try { ...... zygoteServer.registerServerSocket(socketName); if (!enableLazyPreload) { ...... preload(bootTimingsTraceLog); ...... } else { Zygote.resetNicePriority(); } ...... if (startSystemServer) { startSystemServer(abiList, socketName, zygoteServer); } Log.i(TAG, "Accepting command socket connections" ); zygoteServer.runSelectLoop(abiList); zygoteServer.closeServerSocket(); } catch (Zygote.MethodAndArgsCaller caller) { caller.run(); } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception" , ex); zygoteServer.closeServerSocket(); throw ex; } }
首先通过registerServerSocket
方法来创建一个名为zygote
的Server
端的socket
,用于等待ActivityManagerService
请求Zygote
来创建新的应用程序进程。然后预加载类和资源。启动systemServer
进程之后,通过runSelectLoop
方法等待AMS
请求创建新的应用程序进程。
总结一下整个Zygote
进程阶段主要的任务:
创建AndroidRuntime
并调用其start
方法,启动Zygote
进程。
创建java虚拟机并注册JNI
方法。
通过JNI
调用ZygoteInit
的main
方法,使Zygote
从Native
层进入到java
框架层。
通过registerServerSocket
方法创建服务器端Socket
,并通过runSelectLoop
方法等待AMS
请求来创建新的应用程序进程。
启动SystemServer
进程。
2.5 System Server阶段 SystemServer
启动代码仍在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
中。
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 private static boolean startSystemServer (String abiList, String socketName, ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller, RuntimeException { ...... try { ...... pid = Zygote.forkSystemServer( ......); } catch (IllegalArgumentException ex) { throw new RuntimeException (ex); } if (pid == 0 ) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } zygoteServer.closeServerSocket(); handleSystemServerProcess(parsedArgs); } return true ; }
由于SystemServer
进程fork了Zygote
进程,所以该进程也会得到Zygote
进程创建的Socket
,这个Socket
对于SystemServer
进程没有用处,所以需要关闭。最后通过handleSystemServerProcess
方法启动SystemServer
进程。
接下来查看handleSystemServerProcess
方法,其代码位于同样的路径下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 private static void handleSystemServerProcess (ZygoteConnection.Arguments parsedArgs) throws Zygote.MethodAndArgsCaller { ...... if (parsedArgs.invokeWith != null ) { ...... } else { ClassLoader cl = null ; if (systemServerClasspath != null ) { cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); Thread.currentThread().setContextClassLoader(cl); } ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } }
继续跟踪zygoteInit
方法,其代码还是位于同样的路径下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static final void zygoteInit (int targetSdkVersion, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller { if (RuntimeInit.DEBUG) { Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote" ); } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit" ); RuntimeInit.redirectLogStreams(); RuntimeInit.commonInit(); ZygoteInit.nativeZygoteInit(); RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); }
nativeZygoteInit
方法顾名思义是native
层的方法,用来启动Binder
线程池(需要先了解JNI,这里先不解释),这样SystemServer
进程就可以使用Binder
与其他进程进行通信了。applicationInit
方法则是用于进入到SystemServer
的main
方法,对应方法所在路径为/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
。
1 2 3 4 5 6 protected static void applicationInit (int targetSdkVersion, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller { ...... invokeStaticMain(args.startClass, args.startArgs, classLoader); }
invokeStaticMain
方法的代码如下(位于相同路径下):
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 private static void invokeStaticMain (String className, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller { Class<?> cl; try { cl = Class.forName(className, true , classLoader); } catch (ClassNotFoundException ex) { ...... } Method m; try { m = cl.getMethod("main" , new Class [] { String[].class }); } catch (NoSuchMethodException ex) { ...... } catch (SecurityException ex) { ...... } ...... throw new Zygote .MethodAndArgsCaller(m, argv); }
主要是获取SystemServer
的main
方法,并传入MethodAndArgsCaller
异常中,捕获该异常的代码在ZygoteInit.java
的main
方法中(第766行),这个main
方法会调用SystemServer
的main
方法。
1 2 3 4 5 6 7 8 9 try { ...... } catch (Zygote.MethodAndArgsCaller caller) { caller.run(); } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception" , ex); zygoteServer.closeServerSocket(); throw ex; }
当捕获到MethodAndArgsCaller
异常时,就会调用MethodAndArgsCaller
的run
方法,路径为/frameworks/base/core/java/com/android/internal/os/Zygote.java
,代码如下
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 public static class MethodAndArgsCaller extends Exception implements Runnable { private final Method mMethod; 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); } } }
因为我们将SystemServer
的main
方法作为参数传入了MethodAndArgsCaller
异常中,所以mMethod.invoke
即是SystemServer
的main
方法的invoke
,即SystemServer
的main
方法被调用。
所以为什么不直接在invokeStaticMain
方法中调用SystemServer
的main
方法呢,反而是要通过抛出异常来调用?
答:因为在Zygote
启动SystemServer
进程后,SystemServer
进程做了很多准备工作,这使得SystemServer
的main
方法看起来不像是SystemServer
进程的入口方法。而抛出异常的处理会清除所有的设置过程需要的堆栈帧,会使得SystemServer
的main
方法看起来像是SystemServer
进程的入口方法。
SystemServer
的main
方法对应代码路径为/frameworks/base/services/java/com/android/server/SystemServer.java
。
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 public static void main (String[] args) { new SystemServer ().run(); } ...... private void run () { try { ...... Looper.prepareMainLooper(); System.loadLibrary("android_servers" ); performPendingShutdown(); createSystemContext(); mSystemServiceManager = new SystemServiceManager (mSystemContext); mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); SystemServerInitThreadPool.get(); } finally { traceEnd(); } try { traceBeginAndSlog("StartServices" ); startBootstrapServices(); startCoreServices(); startOtherServices(); SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { ...... } finally { traceEnd(); } ...... Looper.loop(); throw new RuntimeException ("Main thread loop unexpectedly exited" ); }
首先会创建消息Looper
、加载库、创建系统context
,然后创建SystemServiceManager
来对系统服务进行创建、启动和生命周期管理。然后会启动各种服务,包括ActivityManagerService
、PackageManagerService
、WindowManagerService
等服务。最后Looper
循环等待接收消息。
总结一下整个System Server
进程阶段的主要任务:
启动Binder
线程池。
创建SystemServiceManager
,用于对系统服务进行创建、启动和生命周期管理。
启动各种系统服务。
2.6 Launcher进程阶段 系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就是Launcher
,通俗来讲就是Android系统的桌面,它是Zygote
进程孵化的第一个APP。Launcher
在启动过程中会请求PackageManagerService
返回系统中已经安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,用户可以通过点击图标来启动相应的应用程序。
Launcher
通过startOtherServices
启动,启动入口为AMS
的systemReady
方法(第1646行),所在路径为frameworks/base/services/java/com/android/server/SystemServer.java
。
1 2 3 4 5 6 7 8 9 10 11 12 private void startOhterServices () { ...... mActivityManagerService.systemReady(() -> { Slog.i(TAG, "Making services ready" ); traceBeginAndSlog("StartActivityManagerReadyPhase" ); mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); ...... } ...... }
查看AMS
的systemReady
方法代码,所在路径为/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
。
1 2 3 4 5 6 7 8 public void systemReady (final Runnable goingCallback, BootTimingsTraceLog traceLog) { ...... synchronized (this ) { ...... mStackSupervisor.resumeFocusedStackTopActivityLocked(); mUserController.sendUserSwitchBroadcastsLocked(-1 , currentUserId); } }
调用了ActivityStackSupervisor
的resumeFocusedStackTopActivityLocked
方法,所在路径为/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
。
1 2 3 4 5 6 7 8 9 10 11 12 boolean resumeFocusedStackTopActivityLocked () { return resumeFocusedStackTopActivityLocked(null , null , null ); }boolean resumeFocusedStackTopActivityLocked ( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (targetStack != null && isFocusedStack(targetStack)) { return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } ...... return false ; }
这里使用了重载,最终都是调用第二个方法,里面调用是ActivityStack
的resumeTopActivityUncheckedLocked
方法,所在路径为/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 boolean resumeTopActivityUncheckedLocked (ActivityRecord prev, ActivityOptions options) { ...... try { mStackSupervisor.inResumeTopActivity = true ; result = resumeTopActivityInnerLocked(prev, options); } finally { mStackSupervisor.inResumeTopActivity = false ; } mStackSupervisor.checkReadyForSleepLocked(); return result; }
该方法主要是调用了resumeTopActivityInnerLocked
方法(在同一个文件中,第2305行)。
1 2 3 4 5 6 private boolean resumeTopActivityInnerLocked (ActivityRecord prev, ActivityOptions options) { ...... return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished" ); ...... }
关键的地方是调用了ActivityStackSupervisor
的resumeHomeStackTask
方法,所在路径为frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
。
1 2 3 4 5 6 7 8 boolean resumeHomeStackTask (ActivityRecord prev, String reason) { ...... if (r != null && !r.finishing) { moveFocusableActivityStackToFrontLocked(r, myReason); return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null ); } return mService.startHomeActivityLocked(mCurrentUser, myReason); }
关键的地方是调用了ActivityService
的startHomeActivityLocked
方法,所在路径为frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
。
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 boolean startHomeActivityLocked (int userId, String reason) { if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null ) { return false ; } Intent intent = getHomeIntent(); ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); if (aInfo != null ) { intent.setComponent(new ComponentName (aInfo.applicationInfo.packageName, aInfo.name)); aInfo = new ActivityInfo (aInfo); aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); ProcessRecord app = getProcessRecordLocked(aInfo.processName, Info.applicationInfo.uid, true ); if (app == null || app.instr == null ) { intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid); final String myReason = reason + ":" + userId + ":" + resolvedUserId; mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason); } } else { Slog.wtf(TAG, "No home screen found for " + intent, new Throwable ()); } return true ; }
创建了一个Intent
,并将mTopAction
和mTopData
传入。mTopAction
的值为Intent.ACTION_MAIN
,并且如果系统运行模式低级工厂模式,则将intent
的Category
设置为android.intent.category.HOME
(具体细节请跟进getHomeIntent
方法查看)。在AndroidManifest
文件(/packages/apps/Launcher3/AndroidManifest.xml
)中查看intent-filter
可以知道,能与该Intent
匹配的是Launcher
。之后就是判断Launcher
是否已经启动,如果没有则调用ActivityStarter
的startHomeActivityLocked
方法启动,所在路径为/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void startHomeActivityLocked (Intent intent, ActivityInfo aInfo, String reason) { mSupervisor.moveHomeStackTaskToTop(reason); mLastHomeActivityStartResult = startActivityLocked(null , intent, null , null , aInfo, null , null , null , null , null , 0 , 0 , 0 , null , 0 , 0 , 0 , null , false , false , mLastHomeActivityStartRecord , null , null , "startHomeActivity: " + reason); if (mSupervisor.inResumeTopActivity) { mSupervisor.scheduleResumeTopActivities(); } }
将Launcher
放入HomeStack
中,HomeStack
是在ActivityStackSupervisor
中定义的用于存储Launcher
的变量。接着调用startActivityLocked
方法来启动Launcher
。
三、总结 以上只是简单的梳理了一遍Android系统启动的流程,整个过程为:设备开机后,处于Boot Loader
阶段,加载并执行引导程序,为操作系统建立好环境之后,将控制权转移给操作系统内核,进入到kernel
阶段。kernel
阶段会启动swapper
进程初始化进程管理、内存管理,加载驱动等相关工作,启动kthreadd
进程,之后会启动init
进程进入到init
阶段。init
阶段会创建和挂载启动所需要的文件目录,初始化和启动属性服务,之后启动zygote
进程进入到zygote
阶段。zygote
阶段会创建java虚拟机并注册JNI
方法,使Zygote
从Native
层进入到java
框架层,创建服务器端Socket
,用于消息通信,之后启动SystemServer
进程进入到SystemServer
阶段。SystemServer
阶段会启动Binder
线程池,创建SystemServiceManager
管理系统服务,之后启动各种系统服务,其中包括Launcher
,就是我们所常见的系统桌面。
然而,本篇文章省略了很多细节,并没有深入分析各个阶段的相关代码,并且在学习的过程中也遇到了一些没有了解过的东西,比如rc
文件以及如何解析rc
文件、 Binder
通信、系统服务的管理、Activity的管理等。这些都需要积累一定的基础,进一步深入学习。
参考:
Android系统启动篇 | BATcoder - 刘望舒 (liuwangshu.cn) (Android系统启动系列篇)
Android 操作系统架构开篇 - Gityuan博客 | 袁辉辉的技术博客 (找系统启动系列篇)
深入研究源码:Android10.0系统启动流程(一) - 知乎 (zhihu.com) (主页找系列篇)
Android系统启动流程 - 简书 (jianshu.com)
Android操作系统启动过程概览 - 知乎 (zhihu.com)
AOSPXRef
《Android进阶解密》