preface
As many years of Android development, I have written many applications, but how does an App start? If you want to say that the desktop starts at one click, that's right. But what about its startup process? With such questions, let's study step by step.
Android startup process
Generally, on any platform, the following components will be loaded and executed step by step:
- Boot loader
- U-boot (optional)
- Kernel
- Android
Android processes have the following order:
- Init
- Zygote
- System Server
- Service Manager
- Other Daemons and processes
- Applications
The specific situation is shown in the figure below. It is interesting to combine the two pictures:
-
Boot ROM: when the power supply is pressed, the boot chip code will be executed from the predefined place (solidified in ROM), load the boot program BootLoader to RAM, and then execute. (this step is designed and implemented by the "chip manufacturer")
-
Boot loader: Bootloader starts to execute. First, it is responsible for completing hardware initialization and booting the operating system. (this step is designed and implemented by the "equipment manufacturer")
-
Kernel: the Linux kernel is the core of Android, responsible for process creation, inter process communication, device driver, file system management, etc. Android applies custom patches on the mainstream kernel to support some functions required for Android operation, such as wake-up lock. The kernel can be loaded as an uncompressed image or a compressed image. When loaded, it mounts the root file system (usually passed as a kernel command-line parameter) and starts the first application in user space. (this step is what needs to be involved in the Android kernel development process)
-
Android: the Linux kernel startup process of Android system and major Linux distributions is similar. The biggest difference between them lies in the difference of init program, because init program determines which daemons and services the system will start and what kind of user UI interface it presents during startup.
Therefore, init program is the core program for analyzing the Android startup process.
-
Init and init.rc: the first user space application executed when starting the kernel is the init executable located in the root folder. This process parses the startup script called the "init. RC" script. This is written in a language specially designed for android. It is used to start all necessary processes, daemons and services for android to run normally. It provides various types of execution time, such as early init, on boot, on post FS, etc. (the ancestor of user space)
-
Demons and Services: init process creates various daemons and processes, such as rild, vold, mediaserver, adb, etc. each process is responsible for its own functions. The description of these processes is beyond the scope of this article. Instead, we will talk more about the "Zygote" process.
-
Service Manager: the service manager process manages all services running in the system. Each service created registers itself in this process, and this information is for future reference by other processes / applications.
-
Zygote: zygote is one of the first init processes created at startup. The term "zygote" is based on biology "the initial cell division formed to produce offspring". Similarly, "zygote in android" initializes Dalivik VM(ART) and fork to create multiple instances to support each Android process. It helps to use shared code between VM instances, thus reducing memory consumption and loading time. It is very suitable for embedded systems. In addition to installing listeners on the server socket, zygote preloads classes and resources for later use in Android applications. When finished, the system server starts.
-
System Server: the System Server process starts all services available in Android.
In this article, we focus on starting from init to application startup.
1. What is Zygote
In Android, zygote is the name of a process. Android is based on the Linux System. When your mobile phone starts up, the Linux kernel will start a process called "init" after loading. In the Linux System, all processes are fork ed out by the init process, and our zygote process is no exception.
Zygote is not only a virtual machine process, but also an incubator of virtual machine instances. Whenever the system requires the execution of an Android application, zygote will fork (split) a sub process to execute the application.
1.1 app_main.cpp
frameworks/base/cmds/app_process/app_main.cpp
After Zygote is started, app_main.cpp will be executed. Whether it is C/c++/java, their entry is main(), just like when we see the Activity, we can directly find the onCreate() method.
1.1.1 main()
int main(int argc, char* const argv[]) { ... //Note 1: initialize AppRuntime(AndroidRunTime) AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); ... // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; String8 niceName; String8 className; ++i; // Skip unused "parent dir" argument. while (i < argc) { const char* arg = argv[i++]; //Note 2: set zygote mode if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = ZYGOTE_NICE_NAME; } ... } Vector<String8> args; if (!className.isEmpty()) { ... } else { // We are in zygote mode. maybeCreateDalvikCache(); // Note 3: in zygote mode, pass the parameter to the ZygoteInit.main() method. if (startSystemServer) { args.add(String8("start-system-server")); } //PROP_VALUE_MAX = 92; char prop[PROP_VALUE_MAX]; ... String8 abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); for (; i < argc; ++i) { args.add(String8(argv[i])); } } if (zygote) { //Note 4: call the AndroidRuntime.start() method runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { ... } else { ... } }
Note 1: initializing AppRuntime is actually Android runtime (Art).
Note 2: set zygote mode.
Note 3: pass the parameter to the ZygoteInit.main() method.
Note 4: start ZygoteInit. ZygoteInit here is the startup class of zygote process. This is discussed below. Let's take a look at the start() method of Android runtime first.
1.2 AndroidRuntime.cpp
frameworks/base/core/jni/AndroidRuntime.cpp
Android virtual machine
1.2.1 start()
/* * Start the Android runtime. This involves starting the virtual machine and calling the "static void main(String[] args)" method in the class named by "className". * * Passes the main function two arguments, the class name and the specified * options string. */ void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { ... JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; //Note 1: start the virtual machine if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) { return; } onVmCreated(env); //Note 2: register Android features (JNI) if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } ... strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); ... /* * Start the virtual machine. This thread becomes the main thread of the VM and will not return until the VM exits. */ char* slashClassName = toSlashClassName(className != NULL ? className : ""); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ... } else { ... jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ... } else { //Note 3 env->CallStaticVoidMethod(startClass, startMeth, strArray); if (env->ExceptionCheck()) threadExitUncaughtException(env); } } ... } Copy code
Note 1: start VM (virtual machine)
Note 2: register Android features (JNI)
Note 3: use JNI to call the main() method of zygotelnit. Zygotelnit here is a class file, that is, it has entered the java field from here.
JNI: a bridge connecting the native(C/C + +) layer and the java layer.
1.3 ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/** * zygote The startup class of the process. */ public class ZygoteInit { ... } Copy code
This is the entry point for the Zygote process. It creates Zygote services, loads resources, and handles other tasks related to the process of preparing to fork into the application.
1.3.1 main()
@UnsupportedAppUsage public static void main(String[] argv) { ZygoteServer zygoteServer = null; try { ... boolean startSystemServer = false; //argv: command line parameter used to specify Zygote configuration. ... if (!enableLazyPreload) { //Note 1: preload resources. preload(bootTimingsTraceLog); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); bootTimingsTraceLog.traceEnd(); // ZygotePreload } ... //Note 2: create the LocalServerSocket of Zygote. zygoteServer = new ZygoteServer(isPrimaryZygote); if (startSystemServer) { //Note 3: start fork ing our system server process. Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); ... } ... // Note 4: zygote permanent cycle. caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { ... } finally { if (zygoteServer != null) { zygoteServer.closeServerSocket(); } } ... } Copy code
Note 1: preload resources.
Note 2: create the LocalServerSocket of Zygote.
Note 3: start fork ing our system server process.
Note 4: zygote permanent cycle.
Let's take a look at forksystem server ();
1.3.2 forkSystemServer()
/** * Prepare the arguments and forks for the system server process. * * @return A {@code Runnable} that provides an entrypoint into system_server code in the child * process; {@code null} in the parent. */ private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { ... //Command line to start system server //The argv in ZygoteInit.main(String argv []) is similar to this String[] args = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023," + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT, "com.android.server.SystemServer", }; //Handle parameter parsing of args related to zygote spawner. ZygoteArguments parsedArgs; int pid; try { ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args); try { parsedArgs = ZygoteArguments.getInstance(commandBuffer); } catch (EOFException e) { throw new AssertionError("Unexpected argument error for forking system server", e); } commandBuffer.close(); ... //Request fork system server process /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, null, parsedArgs.mPermittedCapabilities, parsedArgs.mEffectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } /* For child process */ if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } zygoteServer.closeServerSocket(); return handleSystemServerProcess(parsedArgs); } return null; } Copy code
A system server is started here. Let's take a look at it.
2,SystemServer
System server is also called system server. SystemServer is also a process, including 92 services such as ActivityTaskManagerService, ActivityManagerService, PackageManagerService and WindowManagerService.
There are two very important processes in the Android Framework:
-
SystemServer process.
-
Zygote process.
2.1 SystemServer.java
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer { ... } Copy code
2.1.1 main()
/** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); } public SystemServer() { // Check for factory test mode. mFactoryTestMode = FactoryTest.getMode(); ... } Copy code
Let's see what is used in run()?
2.1.2 run()
private void run() { try { ... // Note 1: load the dynamic library libandroid_service.so. System.loadLibrary("android_servers"); // Note 2: create a system context. createSystemContext(); // Call the mainline module initialization of each process. ActivityThread.initializeMainlineModules(); // Note 3: create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Preparing a thread pool for parallelizable init tasks SystemServerInitThreadPool.start(); ... } finally { } // Note 4: Start services. try { //Let's take a look at what services are started by these three methods startBootstrapServices(t); startCoreServices(t); startOtherServices(t); } catch (Throwable ex) { ... } finally { t.traceEnd(); // StartServices } ... // Note 5: Loop permanent Loop. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); } Copy code
Note 1: load the dynamic library libandroid_service.so.
Note 2: create a system context.
Note 3: create the system service manager.
Note 4: start services (startBootstrapServices, startCoreServices, startOtherServices)
Note 5: Loop permanent Loop.
2.1.3 createSystemContext()
private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); } Copy code
Initialize the system context object mSystemContext and set the default theme. mSystemContext is actually a Context(ContextImpl) object.
When you call ActivityThread.systemMain(), you will call ActivityThread.attach(true). In attach(), you create an Application object and call Application.onCreate().
2.1.4 startBootstrapServices()
/** * Start the system boot service. Because these services have complex interdependencies, they are all placed in this method. */ private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) { ... final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig"; SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG); // Platformcompact service is used by ActivityManagerService, PackageManagerService and other services PlatformCompat platformCompat = new PlatformCompat(mSystemContext); ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat); ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE, new PlatformCompatNative(platformCompat)); AppCompatCallbacks.install(new long[0]); mSystemServiceManager.startService(FileIntegrityService.class); Installer installer = mSystemServiceManager.startService(Installer.class); mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class); mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class); startMemtrackProxyService(); // StartActivityManager ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); //Initialize ActivityManagerService mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); mDataLoaderManagerService = mSystemServiceManager.startService( DataLoaderManagerService.class); mIncrementalServiceHandle = startIncrementalService(); t.traceEnd(); //To initialize powermanagerservice, you need to start it in advance because other services need it. mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); mSystemServiceManager.startService(ThermalManagerService.class); // The power management has been turned on, and the ActivityManagerService is responsible for the power management function mActivityManagerService.initPowerManagement(); mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class); ... mSystemServiceManager.startService(LightsService.class); // Package manager isn't started yet; need to use SysProp not hardware feature if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) { mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS); } // Initialize displaymanagerservice mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); // Start the package manager. try { mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); } finally { } // Now that the PackageManagerService has started, register the dex load reporter to capture any dex files loaded by the system service. // These dex files will be optimized by the BackgroundDexOptService. SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); ... //Add AMS, etc. to ServiceManager mActivityManagerService.setSystemProcess(); if (!mOnlyCore) { boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { } finally { } } } ... mSensorServiceStart = SystemServerInitThreadPool.submit(() -> { TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog(); startSensorService(); }, START_SENSOR_SERVICE); // startBootstrapServices } Copy code
Major changes:
-
Activity task manager service (ATMS): responsible for managing activities and processes, including lifecycle and state switching.
-
ActivityManagerService(AMS): a subclass of AMN, which is responsible for managing three components (except Activity) and processes, including life cycle and state switching. AMS is extremely complex because it interacts with the ui, involving window.
ActivityTaskManagerService: it is generated by stripping Activity related content from ActivityManagerService.
PowerManagerService(PMS): power management service.
Package manager service (PKMs): package management service, not called PMS, is to distinguish it from power management service.
2.1.5 startCoreServices()
/** * Start the core service. */ private void startCoreServices(@NonNull TimingsTraceAndSlog t) { // Service for system config mSystemServiceManager.startService(SystemConfigService.class); // Tracks the battery level. Requires LightService. mSystemServiceManager.startService(BatteryService.class); ... mSystemServiceManager.startService(LooperStatsService.Lifecycle.class); mSystemServiceManager.startService(ROLLBACK_MANAGER_SERVICE_CLASS); mSystemServiceManager.startService(NativeTombstoneManagerService.class); mSystemServiceManager.startService(BugreportManagerService.class); mSystemServiceManager.startService(GpuService.class); // startCoreServices } Copy code
2.1.6 startOtherServices()
/** * Start other services. */ private void startOtherServices(@NonNull TimingsTraceAndSlog t) { final Context context = mSystemContext; VibratorService vibrator = null; DynamicSystemService dynamicSystem = null; IStorageManager storageManager = null; NetworkManagementService networkManagement = null; IpSecService ipSecService = null; VpnManagerService vpnManager = null; VcnManagementService vcnManagement = null; NetworkStatsService networkStats = null; NetworkPolicyManagerService networkPolicy = null; NsdService serviceDiscovery = null; WindowManagerService wm = null; SerialService serial = null; NetworkTimeUpdateService networkTimeUpdater = null; InputManagerService inputManager = null; TelephonyRegistry telephonyRegistry = null; ConsumerIrService consumerIr = null; MmsServiceBroker mmsService = null; HardwarePropertiesManagerService hardwarePropertiesService = null; PacProxyService pacProxyService = null; ... // Now you can start to launch the third-party APP application (such as Launcher desktop) mActivityManagerService.systemReady(() -> { ... }, t); // startOtherServices } Copy code
After the above steps, when we call createSystemContext() to create the system context, we have also completed the creation of mSystemContext and ActivityThread.
ATMS, AMS, WMS, PKMS and other objects have been created, and the initialization of member variables has been completed.
Note: This is the process when the system process is started. After that, the system will be started
Launcher program to complete the loading and display of the system interface.
In the framework design of Android, the server side refers to the system services shared by all apps, such as ATMS, AMS, WMS, PKMS and so on. These basic system services are shared by all apps.
3. What is Launcher
In the Android system, the application is started by the Launcher. In fact, the Launcher itself is also an application. After other applications are installed, a corresponding icon will appear on the Launcher interface. When you click this icon, the Launcher will start the corresponding application.
Of course, you can also start the application in other applications. But it is essentially a call to startActivity().
3.1 LauncherActivity.java
frameworks/base/core/java/android/app/LauncherActivity.java
/** * Displays a list of all activities which can be performed * for a given intent. Launches when clicked. * * @deprecated Applications can implement this UI themselves using * {@link androidx.recyclerview.widget.RecyclerView} and * {@link android.content.pm.PackageManager#queryIntentActivities(Intent, int)} */ @Deprecated public abstract class LauncherActivity extends ListActivity { ... @Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent intent = intentForPosition(position); startActivity(intent); } } Copy code
Summary
A whole drawing is attached
You can take a direct look at what you know about startActivity(). There are too many contents in this article. I'm worried about it myself. I've never seen a wave of attention. The details will be in the next article: ❤️ Android startActivity source code analysis ❤️ Explain in.