Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
preface
As years of Android development, I have written a lot of applications, but how does an App get started? You’re right to say the desktop starts with a click. But what about its startup process? With this question, let’s learn step by step.
Android Startup Process
Typically on any platform, the following components are progressively loaded and executed:
- 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 following figure, which is more interesting when combined:
-
Boot ROM: When the power is pressed, the Boot chip code is executed from a predefined place (solidified in ROM), the Boot program BootLoader is loaded into RAM, and then executed. (This step is designed and implemented by the “chip manufacturer”)
-
Boot Loader: The Bootloader starts to initialize hardware and Boot the operating system. (This step is designed and implemented by the “equipment manufacturer”)
-
Kernel: As the core of Android, the Linux Kernel is responsible for process creation, interprocess communication, device drivers, and file system management. Android applies custom patches to mainstream kernels to support certain features that Android needs to run, such as wakeup locks. The kernel can be loaded as an uncompressed image or a compressed image. At load time, it mounts the root file system (typically passed as a kernel command-line argument) and starts the first application in user space. (This is part of the Android kernel development process.)
-
Android: The main difference between Android and Linux distributions is the init program, which determines which daemons and services will be started and what user interface will be displayed during the startup process.
Therefore, the init program is the core program to analyze the Android startup process.
-
Init and init.rc: The first user-space application executed when the kernel is started is the init executable file in the root folder. The process parses the startup script called the “init.rc” script. This is written in a language designed specifically for Android to launch all the necessary processes, daemons, and services for Android to function properly. It provides various types of execution times, such as early-init, on-boot, on-post-fs, and so on. (The father of user space)
-
Demons and Services: The Init process creates various daemons and processes such as RILd, Vold, Mediaserver, ADB, and more, each responsible for its own functions. Descriptions of these processes are outside the scope of this article. Instead, we’ll 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 available 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 “formed when the initial cell divides to produce offspring”. Similarly, “Zygote in Android” initializes the Dalivik VM(ART) and fork to create multiple instances to support each Android process. It helps to use shared code between VM instances, which reduces memory footprint and load time, making it ideal for embedded systems. In addition to installing listeners on the server socket, Zygote preloads classes and resources that are later used in Android applications. When complete, the system server starts.
-
SystemServer: The SystemServer process starts all services available in Android.
In this article we focus on starting with init and starting with the application.
What is Zygote
In Android, zygote is the name of a process. Android is based on the Linux System, and when your phone is turned on, the Linux kernel is loaded and a process called “init” starts. In Linux, all processes are forked by the init process, and zygote is no exception.
Zygote is a virtual machine process and an incubator for virtual machine instances, forking out a child process to execute an Android application whenever the system requests it.
1.1 app_main. CPP
frameworks/base/cmds/app_process/app_main.cpp
App_main.cpp is executed after Zygote is started. Whether it’s C/ C ++/ Java, their entry point is main(), just like when we see an Activity we go to the onCreate() method.
1.1.1 the main ()
int main(int argc, char* const argv[])
{...// Note 1: Initializing 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(a);// Note 3: In zygote mode, the arguments are passed to the zygoteinit.main () method.
if (startSystemServer) {
args.add(String8("start-system-server"));
}
/ / PROP_VALUE_MAX = 92;
charprop[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 androidRuntime.start ()
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
...
} else{... }}Copy the code
Note 1: Initialize AppRuntime, which is AndroidRuntime(ART).
Note 2: Set zygote mode.
Note 3: Pass the argument to the zygoteinit.main () method.
Note 4: Start ZygoteInit. Here ZygoteInit is the zygote process startup class. I’ll talk about that next. Let’s look at the start() method in AndroidRuntime.
1.2 AndroidRuntime. CPP
frameworks/base/core/jni/AndroidRuntime.cpp
Android virtual machine
1.2.1 the 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 a VM
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 VM. This thread becomes the main thread of the VM and is not returned 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 {
/ / comment 3
env->CallStaticVoidMethod(startClass, startMeth, strArray);
if (env->ExceptionCheck())
threadExitUncaughtException(env); }}... }Copy the code
Note 1: Start the VM(virtual machine)
Note 2: Sign up for Android features (JNI)
Note 3: The main() method of Zygotelnit is called with JNI. Zygotelnit in this case is a class file, which means you’re in Java territory from here on out.
JNI: Bridge between native(C/C++) layer and Java layer.
1.3 ZygoteInit. Java
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/** * Start class for zygote process. * /
public class ZygoteInit {... }Copy the code
This is the entry point for the Zygote process. It creates the Zygote service, loads resources, and handles other tasks related to the process of preparing to fork into the application.
1.3.1 the main ()
@UnsupportedAppUsage
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
try{...boolean startSystemServer = false;
Argv: used to specify command line arguments for Zygote configuration..if(! enableLazyPreload) {// Comment 1: Preload resources.
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload}...// Note 2: Create LocalServerSocket for Zygote.
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
// Note 3: Start forking our SystemServer process.Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); . }...// Note 4: Zygote permanent loop.
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
...
} finally {
if(zygoteServer ! =null) { zygoteServer.closeServerSocket(); }}... }Copy the code
Note 1: Preload resources.
Note 2: Create LocalServerSocket for Zygote.
Note 3: Start forking our SystemServer process.
Note 4: Zygote permanent loop.
ForkSystemServer ();
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 SystemServer
Zygoteinit. main(String argv[]) argv is similar to this
String[] args = {
"--setuid=1000"."--setgid=1000"."- setgroups = 1001100 2100 3100 4100 5100 6100 7100 8100 9101 0101 8102 1102 3,"
+ "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 resolution of args associated with 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 the code
A System Server is started. Let’s take a look at him.
2, SystemServer
SystemServer is also SystemServer. SystemServer is also a process, including ActivityTaskManagerService, ActivityManagerService, PackageManagerService, WindowManagerService etc. 92 kinds of services.
There are two very important processes in the Android Framework:
-
SystemServer process.
-
The Zygote process.
2.1 SystemServer. Java
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {... }Copy the code
2.1.1 the main ()
/** * The main entry point from zygote. */
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer(a) {
// Check for factory test mode.mFactoryTestMode = FactoryTest.getMode(); . }Copy the code
Let’s see what we use in run ().
2.1.2 the run ()
private void run(a) {
try{...// Note 1: load the dynamic library libandroid_service.so.
System.loadLibrary("android_servers");
// Note 2: Create system context.
createSystemContext();
// Call mainline module initialization for each process.
ActivityThread.initializeMainlineModules();
// Note 3: Create SystemServiceManager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare thread pools for parallelizable init tasksSystemServerInitThreadPool.start(); . }finally{}// Note 4: Start services.
try {
// Let's look at the three methods to start what service
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 the code
Note 1: Load the dynamic library libandroid_service.so.
Note 2: Create system context.
Note 3: Create SystemServiceManager.
Note 4: Start services (startBootstrapServices, startCoreServices, startOtherServices)
Note 5: Loop permanent Loop.
2.1.3 createSystemContext ()
private void createSystemContext(a) {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
Copy the code
Initialize the system Context object mSystemContext, which is actually a Context(ContextImpl) object, and set the default theme.
Call ActivityThread. SystemMain (), invokes ActivityThread. Attach (true), and in the attach (), and create the Application object, And calls application.oncreate ().
2.1.4 startBootstrapServices ()
/** * Start the system boot service, because these services have complex interdependencies, so they are placed in this method. * /
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {...final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
PlatformCompat 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();
// Initialize PowerManagerService, which needs to be started early because other services need it.
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
mSystemServiceManager.startService(ThermalManagerService.class);
// Power management is enabled. ActivityManagerService is responsible for power managementmActivityManagerService.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(display manager)
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 is started, register the dex load reporter to capture any dex files loaded by the system service.
// These dex files will be optimized by BackgroundDexOptService.SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); .// Add AMS and so on to the 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 the code
Major changes:
-
ActivityTaskManagerService (ATMS) : responsible for the management activities and processes, including life cycle and state switch.
-
ActivityManagerService(AMS) : A subclass of AMN that manages three components (except activities) and processes, including life cycles and state transitions. AMS is extremely complex because it interacts with the UI and involves Windows.
ActivityTaskManagerService: the Activity related content from ActivityManagerService spun off.
PowerManagerService(PMS) : power management service.
PackageManagerService(PKMS) : Package management service. It is not called PMS to distinguish it from power management service.
2.1.5 startCoreServices ()
/** * Start core services. * /
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 the 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 a three-party APP (such as Launcher)
mActivityManagerService.systemReady(() -> {
...
}, t);
// startOtherServices
}
Copy the code
After the above steps, we created the mSystemContext and ActivityThread when we called createSystemContext() to create the system context.
Objects such as ATMS, AMS, WMS, PKMS and so on have been created and initialized with member variables.
Note: this is the process of starting the system, after which the system will be started
Launcher program, 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 mentioned here. These basic system services are common to all apps.
3. What is Launcher
In the Android system, an application is launched by the Launcher. In fact, the Launcher itself is also an application. After other applications are installed, a corresponding icon appears on the interface of the Launcher.
You can also launch an application in another application. But essentially it’s all about calling 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 the code
summary
A complete drawing is attached
Check out startActivity() if you know anything about it. It’s too much for me to watch. Haven’t seen the attention to go a wave, detailed content will be next article: ❤️ Android startActivity source code analysis ❤️.