It feels good to use Markdown for the first time.
How does the Android system go from pressing the enable key to launcher? What are the operations in the middle? Start the source code journey with these questions.
Like a windows operating system, each system starts with a boot program. In linux, when the boot program starts the linux kernel, various drivers and data structures are loaded, after the driver is installed, start to load the Android system and start the first process in the linux World: init process.
In main of init. c:
Int main (int argc, char ** argv) {umask (0); // clear the default object attribute mkdir (/dev, 0755 ); // create and mount a file ........ init_parse_config_file (/init. rc); // parse the file .........}
In the init. rc file: (the file is in the system/core/rootdir directory)
// Set some global environment variables: export PATH/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin export LD_LIBRARY_PATH/vendor/lib: /system/lib .............. // create the basic file system structure mkdir/data/misc 01771 system misc .............. // start some services: 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 .............
The most important thing is this zygote process. zygote is an incubator. Like the parent process, many sub-processes can be fork, which is a parent process of Android, it is used to start other service processes of Android. After media, netd, and other service processes are destroyed, the zygote process automatically restarts these service processes.
In the App_Main.cpp file:
int main(int argc, const char* const argv[]){ ............................ bool startSystemServer = (i < argc) ? strcmp(argv[i], --start-system-server) == 0 : false; setArgv0(argv0, zygote); set_process_name(zygote); runtime.start(com.android.internal.os.ZygoteInit,startSystemServer); }
In the start method of AndroidRuntime
Void AndroidRuntime: start (const char * className, const bool startSystemServer ){.................... // enable the Java Virtual Machine and load the jni runtime environment if (startVm (& mJavaVM, & env )! = 0) goto bail ;............. // use jni to interact with java and load the ZygoteInit class startClass = env-> FindClass (slashClassName); if (startClass = NULL) {LOGE (JavaVM unable to locate class '% s', slashClassName);} else {// call the main method startMeth = env-> GetStaticMethodID (startClass, main, ([Ljava/lang/String;) V); if (startMeth = NULL) {LOGE (JavaVM unable to find main () in '% s', className );} else {env-> CallStaticVoidMethod (startClass, startMeth, strArray); if (env-> ExceptionCheck () threadExitUncaughtException (env );}}
In ZygoteInit. java:
Public static void main (String argv []) {// sets the minimum heap size for Android runtime to 5 MB VMRuntime. getRuntime (). setMinimumHeapSize (5*1024*1024 );.............. // pre-load some frequently-used classes. About 2.3 of these frequently-used classes exist, in the 4.2 source code, there are more than 2400 frequently-used mobile phones. For example, some mobile phone manufacturers can start their phones quickly. It is estimated that preloadClasses () has been optimized here (); // load some resource files. xml files such as array, drawable, and color are preloadResources ();.............. if (argv [1]. equals (true) {// In the SystemServer class, fork system service process startSystemServer ();} else If (! Argv [1]. equals (false) {throw new RuntimeException (argv [0] + USAGE_STRING);} private static boolean startSystemServer () throws MethodAndArgsCaller, RuntimeException {String args []; string ashmem_size = System. getProperty (gralloc. ashmem_size); if (null! = Ashmem_size) & (0! = Random () {args = new String [] {-- setuid = 1000, -- setgid = 1000, -- setgroups = 1001,1002, 1003,1004, 1005,1006, 1007,1008, 1009,1010, 1018,3001, 3006, -- capabilities = 1300000352,1300000352, -- rlimit = 8, -- runtime-init, -- nice-name = system_server, com. android. server. systemServer,}; args [4] = args [4]. concat (ashmem_size); args [4] = args [4]. concat (,); args [4] = args [4]. concat (ashmem_size);} else {args = new String [] {-- setuid = 1000, -- setgid = 1000, -- setgroups = 1001,1002, 1003,1004, 1005,1006, 1007,1008, 1009,1010, large, 3006, -- capabilities = 1300000352,1300000352, -- runtime-init, -- nice-name = system_server, com. android. server. systemServer ,};}.............................. pid = Zygote. forkSystemServer (parsedArgs. uid, parsedArgs. gid, parsedArgs. gids, debugFlags, rlimits, parsedArgs. permittedCapabilities, parsedArgs. effectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException (ex );}
In the SystemServer class:
native public static void init1(String[] args); ......... System.loadLibrary(android_servers); init1(args); ......... }
First, load the so library android_servers, which is located in the jni directory of the systemServer parent directory at the same level. The corresponding c file is com_android_server_SystemServer.c. Then call the init1 method in the library,
extern C int system_init(); static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz) { system_init(); } static JNINativeMethod gMethods[] = { { init1, ([Ljava/lang/String;)V, (void*) android_server_SystemServer_init1 }, };
We can see that init1 is registered to the android_server_SystemServer_init1 method, and the system_init method is called in the android_server_SystemServer_init1 method, which appears in System_init.cpp.
Extern C status_t system_init () {// enable the sensor service SensorService: instantiate (); if (! Proc-> supportsProcesses () {AudioFlinger: instantiate (); // start the media playback service MediaPlayerService: instantiate (); CameraService: instantiate (); AudioPolicyService :: instantiate () ;}// start AndroidRuntime * runtime = AndroidRuntime: getRuntime ();................. runtime-> callStatic (com/android/server/SystemServer, init2 );................. return NO_ERROR;
In the System_init.cpp class system_init () method: Use runtime to call the init2 method of SystemServer. The init2 method is described as follows:
Public static final void init2 () {// start to enter the Android system service Thread thr = new ServerThread (); thr. setName (android. server. serverThread); thr. start ();}
In the run method:
........... // Instantiate various system services. main (context, factoryTest = SystemServer. FACTORY_TEST_LOW_LEVEL); Slog. I (TAG, System Content Providers); ActivityManagerService. installSystemProviders (); Slog. I (TAG, Battery Service); battery = new BatteryService (context); ServiceManager. addService (battery, battery); Slog. I (TAG, Lights Service); lights = new LightsService (context );............ serviceManager. addService (vibrator, new VibratorService (context ));............ (ActivityManagerService) ActivityManagerNative. getDefault ()). systemReady (new Runnable () {public void run (){........});
The ServerThread task is mainly a new out-of-system service, and then added to serviceManager for unified management. Finally, mMainStack is executed in the systemReady method of ActivityManagerService. resumeTopActivityLocked (null); that is, the first activity is enabled.
Final boolean resumeTopActivityLocked (ActivityRecord prev) {// find the first activity ActivityRecord next = finished (null) that has not been completed; final boolean userLeaving = mUserLeaving; mUserLeaving = false; if (next = null) {if (mMainStack) {// No activity, start launcher return mService. startHomeActivityLocked ();}}.....................}
By now, the first activity in the Android world has been successfully started, which is the main activity in the Launcher.