android的init進程用來啓動zygote進程,用來啓動android世界。
init進程的源碼在頂層目錄的/system/core/init
使用 find -name Android.mk -exec grep -l "init" {} \;來查找源碼,接下來的android服務程序也是使用這個指令來查找源碼。java
/system/core/init/init.c
整個init進程的入口函數
669 int main(int argc, char **argv)
init_parse_config_file("/init.rc");
snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
722 init_parse_config_file(tmp);
解析兩個文件腳本文件。解析完以後按條件觸發事件,最後程序進入死循環,輪詢監控屬性、按鍵、信號android
android裏面兩個重要的進程爲。zygote和servermanger兩個服務。
431 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
432 class main
433 socket zygote stream 666
434 onrestart write /sys/android_power/request_state wake
435 onrestart write /sys/power/state on
436 onrestart restart media
437 onrestart restart netd
438 c++
find -name Android.mk -exec grep -l "app_process" {} \;用來查找zygote服務的源碼。
源碼路徑/android4.0/frameworks/base/cmds/app_process$
app_main.cpp爲zygote進程的程序入口 。
無論是java、c++仍是c程序的入口都是main數組
zygote = true;
niceName = "zygote";
startSystemServer = true;app
if (zygote) {
189 runtime.start("com.android.internal.os.ZygoteInit", "start-system-server");socket
調用runtime的start方法,在runtime的祖先類內定義。
在frameworks/base/core/jni/AndroidRuntime.cpp
99 void AndroidRuntime::start(const char* className, const char* options)
800 {
/* start the virtual machine */
831 JNIEnv* env;
832 if (startVm(&mJavaVM, &env) != 0) {
833 return;
834 }
835 onVmCreated(env);
836
837 /*函數
com/android/internal/os/ZygoteInit"rest
爲接下來進入java環境準備參數,準備一個java環境string數組
855 stringClass = env->FindClass("java/lang/String");
856 assert(stringClass != NULL);
857 strArray = env->NewObjectArray(2, stringClass, NULL);
858 assert(strArray != NULL);
859 classNameStr = env->NewStringUTF(className);
860 assert(classNameStr != NULL);
861 env->SetObjectArrayElement(strArray, 0, classNameStr);
862 optionsStr = env->NewStringUTF(options);
863 env->SetObjectArrayElement(strArray, 1, optionsStr);server
strArray[2] = {"com.android.internal.os.ZygoteInit", "start-system-server"};進程
866 * Start VM. This thread becomes the main thread of the VM, and will
867 * not return until the VM exits.
868 */
869 char* slashClassName = toSlashClassName(className);包名轉換爲路徑
870 jclass startClass = env->FindClass(slashClassName); 在c環境找java類文件
871 if (startClass == NULL) {
872 LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
873 /* keep going */
874 } else {
875 jmethodID startMeth = env->GetStaticMethodID(startClass, "main", 在找到的java文件內找void main(string[])方法
876 "([Ljava/lang/String;)V");
877 if (startMeth == NULL) {
878 LOGE("JavaVM unable to find main() in '%s'\n", className);
879 /* keep going */
880 } else {
881 env->CallStaticVoidMethod(startClass, startMeth, strArray); 從c環境跳到java世界並帶有參數
882
java世界:
find -name main
android4.0/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java android、世界下整個java世界的開始
if (argv[1].equals("start-system-server")) {
536 startSystemServer(); 根據傳遞的參數 決定是否啓動system_server服務
system_server服務的源碼在:android4.0/frameworks/base/services/java/com/android/server/SystemServer.java
--------------->>>>>>
native public static void init1(String[] args); 被native修飾過的函數就是一個jni函數,在c、環境下。
SystemServer.java找到他的入口。main
System.loadLibrary("android_servers"); 從java世界跳轉到c環境,須要先將c環境的庫文件進行加載,加載好了以後再進行跳轉。
init1(args);
find -name Android.mk -exec grep -l "android_servers" {} \;
/android4.0/frameworks/base/services/jni/com_android_server_SystemServer.cpp
static JNINativeMethod gMethods[] = {
35 /* name, signature, funcPtr */
36 { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 }, jni提早寫好了關係,將java調用的本地代碼和c裏面的執行函數進行關聯
37 };
所以執行的是android_server_SystemServer_init1函數
24 extern "C" int system_init(); 說明來自另一個c++文件名爲system_init.cpp
find -name system_init.cpp 文件在
android4.0/frameworks$ /base/cmds/system_server/library/system_init.cpp
system_init啓動了兩個服務SensorService、SurfaceFlinger而且調回java,執行init2(); jclass clazz = env->FindClass("com/android/server/SystemServer"); 94 if (clazz == NULL) { 95 return UNKNOWN_ERROR; 96 } 97 jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V"); 98 if (methodId == NULL) { 99 return UNKNOWN_ERROR;100 }101 env->CallStaticVoidMethod(clazz, methodId); 回到java環境,執行init2