一、启动电源以及系统启动
当电源按下时引导芯片代码从预定义的地方(固化在ROM)开始执行。加载引导程序BootLoader到RAM中,然后执行。
二、引导程序BootLoader
这是Android操作系统开始运行前的一个小程序,主要作用是初始化基本的硬件设备,建立内存空间映射, 为装载linux内核准备好运行环境,当linux内核加载完毕之后,bootloder就会从内存中清除。
三、Linux内核启动
当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。在内核完成系统设置后,它首先在系统文件中寻找init.rc文件,并启动init进程。
四、init进程启动
init进程是Linux创建的第一个进程,主要做了一下三件事:
(1)创建和挂载启动所需的文件目录。
(2)初始化和启动属性服务。
(3)解析init.rc配置文件并启动Zygote进程。
五、Zygote进程启动
Zygote进程是所有进程的父进程,Zygote进程初始化的时候会创建Dalivik虚拟机,预装载系统的资源文件和java类,通过fock(复制进程)的形式来创建应用程序进程和运行系统的关键服务的SystemServer进程,所有从Zygote进程fock出的用户进程将继承和共享这些资源(在内部获取一个DVM的实例副本),不用浪费时间重新加载。在这之后,Zygote进程也将变为守护进程,负责响应启动APK应用的启动请求。
首先由app_process可执行文件创建AppRuntime(具体代码见下文)并调用其start方法,启动Zygote进程,再创建Java虚拟机并为Java虚拟机注册JNI方法,通过JNI调用了ZygoteInit的main函数进入Zygote的Java框架层,这就从C++代码跳到了java代码。ZygoteInit类通过调用zygoteServer的registerServerSocket方法来创建一个Server端的Socket,再通过runSelectLoop方法来等待AMS请求创建新的应用程序进程。由上图可以看出,ZygoteInit类还做了两件事:预加载类和资源、启动SystemServer进程。Zygote进程将SystemServer进程启动之后,就会转为守护进程,在这个服务器端的Socket上等待AMS请求。
下面具体来看看启动SystemServer进程。
六、SystemServer进程启动
SystemServer进程是Zygote进程fork出的第一个进程,也是整个Android系统的核心进程,在SystemServer主要运行的是Binder服务,通过nativeZygoteInit函数启动Binder线程池,SystemServer进程可以使用Binder与其他进程进行通信。再创建SystemServiceManager,用于对系统的服务进行创建、启动和生命周期管理。SystemServer首要启动本地服务 SensorService ,接着启动 ActivityManagerService,WindowsManagerService,PackgeManagerService等在内的所有java服务。
七、Launcher启动
系统启动的最后一步是启动一个应用程序用来显示系统中已经安装的应用程序,这个应用程序就叫作Launcher。Launcher在启动过程中会请求PackageManagerService返回系统中已安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户就可以通过点击这些快捷图标来启动相应的应用程序。
启动Launcher的入口为AMS的systemReady方法(具体调用代码见后文),代码调用顺序见Launcher启动过程的时序图,最终resumeHomeStackTask方法中调用了AMS的startHomeActivityLocked方法。将Launcher放入HomeStack中,接着调用startActivityLocked方法来启动Launcher,剩余的过程和Activity的启动过程类似。下篇讲Activity的启动过程。最终进入Launcher的onCreate方法中,到这里Launcher就完成了启动。
具体代码执行的流程如下:
-
Init进程首先加载一个init.rc配置文件(Android启动脚本),代码如下:
int main(int argc, char **argv) { // 创建文件夹 挂载 mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755"); mkdir("/dev/pts", 0755); // 打开日志 log_init(); INFO("reading config file\n"); // 加载init.rc配置文件 init_parse_config_file("/init.rc"); }
-
init.rc配置文件会进行很多的配置,创建很多的文件夹及文件,然后初始化一些Android驱动器,之后该配置文件最重要的一个任务就是启动一个Zygote(孵化器)进程,此进程是Android系统的一个父进程,用来启动Android的其他服务进程,代码如下:
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 onrestart restart media onrestart restart netd
-
Zygote会执行一个app_process可执行文件,在这个文件中首先添加了Android运行时环境,在Android运行时中调用了ZygoteInit类,这就从C++代码跳到了java代码。
int main(int argc, const char* const argv[]) { ... // Android运行时环境 AppRuntime runtime; ... // Next arg is startup classname or "--zygote" if (i < argc) { arg = argv[i++]; if (0 == strcmp("--zygote", arg)) { bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false; setArgv0(argv0, "zygote"); set_process_name("zygote"); // 启动java代码 runtime.start("com.android.internal.os.ZygoteInit", ... }
-
进入AppRuntime.start方法。因为AppRuntime继承AndroidRuntime。所以会调用到AndroidRuntime.start方法:注册一系列本地函数到虚拟机,通过反射机制找到ZygoteInit.main方法并执行。
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { //app_main.cpp runtime.start("com.android.internal.os.ZygoteInit", args, zygote); //className:com.android.internal.os.ZygoteInit zygote:true ... //注册JNI本地函数 if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } ... if (startClass == NULL) { ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { //ZygoteInit 通过反射找到zygoteInit.main的方法ID。 jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ALOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { //执行zygoteinit.main方法,zygoteinit类为java类 env->CallStaticVoidMethod(startClass, startMeth, strArray); ... }
-
在ZygoteInit.main.java代码中首先设置了Java虚拟机的堆内存空间,然后启动一个类加载器加载Android启动依赖的类比如Activity等四大组件,dialog等UI的类,然后分出一个子进程启动SystemServer系统服务
// ZygoteInit.mian public static void main(String argv[]) { try { VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024); //1.注册socket // 2.加载Android依赖的类 preloadClasses(); //cacheRegisterMaps(); preloadResources(); ... if (argv[1].equals("true")) { // 3.启动系统服务进程,最终调用SystemServer.main方法 startSystemServer(); } else if (!argv[1].equals("false")) { ... // 4.进入循环 } private static boolean startSystemServer() ... args = new String[] { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006", "--capabilities=130104352,130104352", "--rlimit=8,", "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", ... /* Request to fork the system server process */ // 母进程开始分叉服务 启动SystemServer pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, debugFlags, rlimits, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); ... }
-
在SystemServer.main里初始化SystemServer对象,再调用对象的run()方法
public final class SystemServer { ... public static void main(String[] args) { //先初始化SystemServer对象,再调用对象的run()方法, new SystemServer().run(); } }
-
SystemServer.run()用于启动各种系统服务
private void run() { //当系统时间比1970年更早,就设置当前系统时间为1970年 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } //变更虚拟机的库文件,对于Android 6.0默认采用的是libart.so SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); if (SamplingProfilerIntegration.isEnabled()) { ... } //清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间 VMRuntime.getRuntime().clearGrowthLimit(); //设置内存的可能有效使用率为0.8 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // 针对部分设备依赖于运行时就产生指纹信息,因此需要在开机完成前已经定义 Build.ensureFingerprintProperty(); //访问环境变量前,需要明确地指定用户 Environment.setUserRequired(true); //确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority) BinderInternal.disableBackgroundScheduling(true); android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); // 主线程looper就在当前线程运行 Looper.prepareMainLooper(); //加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下 System.loadLibrary("android_servers"); //检测上次关机过程是否失败,该方法可能不会返回[见小节1.2.1] performPendingShutdown(); //初始化系统上下文 createSystemContext(); //创建系统服务管理 mSystemServiceManager = new SystemServiceManager(mSystemContext); //将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); //启动各种系统服务 try { startBootstrapServices(); // 启动引导服务 startCoreServices(); // 启动核心服务 startOtherServices(); // 启动其他服务 } catch (Throwable ex) { Slog.e("System", "************ Failure starting system services", ex); throw ex; } //用于debug版本,将log事件不断循环地输出到dropbox(用于分析) if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread."); } //一直循环执行 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
-
startBootstrapServices方法里主要去启动AMS(ActivityManagerService)
private void startBootstrapServices() { ... //启动AMS服务 mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); //设置AMS的系统服务管理器 mActivityManagerService.setSystemServiceManager(mSystemServiceManager); //设置AMS的APP安装器 mActivityManagerService.setInstaller(installer); //初始化AMS相关的PMS mActivityManagerService.initPowerManagement(); ... //设置SystemServer mActivityManagerService.setSystemProcess();
-
startOtherServices方法会调用ActivityManagerService.systemReady方法
private void startOtherServices() { ... SystemConfig.getInstance(); mContentResolver = context.getContentResolver(); // resolver ... mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); // mount mPackageManagerService.performBootDexOpt(); // dexopt操作 ActivityManagerNative.getDefault().showBootMessage(...); //显示启动界面 ... // 准备好window, power, package, display服务 wm.systemReady(); mPowerManagerService.systemReady(...); mPackageManagerService.systemReady(); mDisplayManagerService.systemReady(...); //重头戏 mActivityManagerService.systemReady(new Runnable() { public void run() { ... } }); }
-
在ActivityManagerService的sysytemReady方法中,最关键的是startHomeActivityLocked和resumeTopActivityLocked两个方法,这两者都可以启动lucher应用的锁屏界面
public void systemReady(final Runnable goingCallback) { synchronized(this) { if (mSystemReady) { // If we're done calling all the receivers, run the next "boot phase" passed in // by the SystemServer if (goingCallback != null) { goingCallback.run(); } return; } // Make sure we have the current profile info, since it is needed for // security checks. updateCurrentProfileIdsLocked(); .................................... 此处省略大量代码 // Start up initial activity. mBooting = true; //打开 startHomeActivityLocked(mCurrentUserId, "systemReady"); try { if (AppGlobals.getPackageManager().hasSystemUidErrors()) { Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" + " data partition or your device will be unstable."); mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); } } catch (RemoteException e) { } if (!Build.isFingerprintConsistent()) { Slog.e(TAG, "Build fingerprint is not consistent, warning user"); mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); } long ident = Binder.clearCallingIdentity(); try { Intent intent = new Intent(Intent.ACTION_USER_STARTED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException { } }, 0, null, null, INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } catch (Throwable t) { Slog.wtf(TAG, "Failed sending first user broadcasts", t); } finally { Binder.restoreCallingIdentity(ident); } //打开第一个activity mStackSupervisor.resumeTopActivitiesLocked(); sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); } }
-
startHomeActivityLocked方法启动home界面
boolean startHomeActivityLocked(int userId, String reason) { if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) { // We are running in factory test mode, but unable to find // the factory test app, so just sit around displaying the // error message and don't try to start anything. 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)); // Don't do this if the home app is currently being // instrumented. aInfo = new ActivityInfo(aInfo); aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); ProcessRecord app = getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid, true); if (app == null || app.instrumentationClass == null) { intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); mStackSupervisor.startHomeActivity(intent, aInfo, reason); } } return true; }
-
通过ActivityStack的resumeTopActivityLocked方法调用startHomeActivityLocked来启动home界面
final boolean resumeTopActivityLocked(ActivityRecord prev) { // Find the first activity that is not finishing. // 没有已经打开的Activity, next为 null ActivityRecord next = topRunningActivityLocked(null); // Remember how we'll process this pause/resume situation, and ensure // that the state is reset however we wind up proceeding. final boolean userLeaving = mUserLeaving; mUserLeaving = false; if (next == null) { // There are no more activities! Let's just start up the // Launcher... if (mMainStack) { // 启动lucher应用的锁屏界面 return mService.startHomeActivityLocked(); } } ... }
-
startHomeActivityLocked有一个很关键的方法:getHomeIntent(),它就是打开launcher应用的Intent。
Intent getHomeIntent() { Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); intent.setComponent(mTopComponent); if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { intent.addCategory(Intent.CATEGORY_HOME); } return intent; }