在android上,如果你直接用dalivik去載入framework.jar,你會發現裡面的大部分native方法無法使用。同時,在/init.rc裡面,你也找不到dalvikvm。在ps列表,也沒有dalvikvm。那android是怎麼啟動java程式的呢?
在android上,java程式是通過app_process啟動的。在/init.rc裡面,有如下一段代碼:
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
app_process的命令列參數如下:
app_process [java-options] cmd-dir start-class-name [options]
因此,init.rc裡面的各個參數的對應關係為:
-Xzygote: java-options,這些參數會傳給dalvik,這些參數必須以-開頭,一旦遇到不是以-開頭的或者--,代表java-options結束。
/system/bin:cmd-dir,也就是目前的目錄,檔案操作的父路徑將為此路徑。
start-class-name:空
--zygote --start-system-server:選項。
if (i < argc) {<br />arg = argv[i++];<br />if (0 == strcmp("--zygote", arg)) {<br />bool startSystemServer = (i < argc) ?<br />strcmp(argv[i], "--start-system-server") == 0 : false;<br />setArgv0(argv0, "zygote");<br />set_process_name("zygote");<br />runtime.start("com.android.internal.os.ZygoteInit",<br />startSystemServer);<br />} else {<br />set_process_name(argv0);<br />runtime.mClassName = arg;<br />// Remainder of args get passed to startup class main()<br />runtime.mArgC = argc-i;<br />runtime.mArgV = argv+i;<br />LOGV("App process is starting with pid=%d, class=%s./n",<br />getpid(), runtime.getClassName());<br />runtime.start();<br />}<br />}
從app_process的main函數(在app_main.cpp裡面)可以看出,app_process有兩種啟動方式:一種是init.rc裡面的這種方式,這種方式將會以zygote模式啟動com.android.internal.os.ZygoteInit,並將進程名稱改為zygote;另外一種是以非zygote類比啟動com.android.internal.os.RuntimeInit,並調用它的main方法,main的最後會執行finishInit,finishInit是一個native方法,這個方法會調用app_process的onStarted方法,在onStarted裡面將會調用真正要執行的class。
無論app_process,它都將會調用frameworks/base/core/jni/AndroidRuntime.cpp裡面的start
方法(496行)。這 個start方法會根據android屬性系統設定dalvik的參數,並初始化java代碼的native方法,最終啟動dalvik。需要注意的是,java代碼的大部分native方法(差不多80%)都是在這裡面初始化的,這些初始化代碼會檢查java代碼的正確性(例如是否有對應的native方法,是否有需要的屬性等),在初始化過程中,任何一步的錯誤都將導致進程退出。整個native方法初始化過程如下:start(AndroidRuntime.cpp,766行)->startReg(AndroidRuntime.cpp,1136行)-> register_jni_procs(AndroidRuntime.cpp,1011行)。初始化的java class有(AndroidRuntime.cpp,1018行):
static const RegJNIRec gRegJNI[] = {<br />REG_JNI(register_android_debug_JNITest),<br />REG_JNI(register_com_android_internal_os_RuntimeInit),<br />REG_JNI(register_android_os_SystemClock),<br />REG_JNI(register_android_util_EventLog),<br />REG_JNI(register_android_util_Log),<br />REG_JNI(register_android_util_FloatMath),<br />REG_JNI(register_android_text_format_Time),<br />REG_JNI(register_android_pim_EventRecurrence),<br />REG_JNI(register_android_content_AssetManager),<br />REG_JNI(register_android_content_StringBlock),<br />REG_JNI(register_android_content_XmlBlock),<br />REG_JNI(register_android_emoji_EmojiFactory),<br />REG_JNI(register_android_security_Md5MessageDigest),<br />REG_JNI(register_android_text_AndroidCharacter),<br />REG_JNI(register_android_text_KeyCharacterMap),<br />REG_JNI(register_android_os_Process),<br />REG_JNI(register_android_os_Binder),<br />REG_JNI(register_android_os_Hardware),<br />REG_JNI(register_android_view_Display),<br />REG_JNI(register_android_nio_utils),<br />REG_JNI(register_android_graphics_PixelFormat),<br />REG_JNI(register_android_graphics_Graphics),<br />REG_JNI(register_android_view_Surface),<br />REG_JNI(register_android_view_ViewRoot),<br />REG_JNI(register_com_google_android_gles_jni_EGLImpl),<br />REG_JNI(register_com_google_android_gles_jni_GLImpl),<br />REG_JNI(register_android_graphics_Bitmap),<br />REG_JNI(register_android_graphics_BitmapFactory),<br />REG_JNI(register_android_graphics_Camera),<br />REG_JNI(register_android_graphics_Canvas),<br />REG_JNI(register_android_graphics_ColorFilter),<br />REG_JNI(register_android_graphics_DrawFilter),<br />REG_JNI(register_android_graphics_Interpolator),<br />REG_JNI(register_android_graphics_LayerRasterizer),<br />REG_JNI(register_android_graphics_MaskFilter),<br />REG_JNI(register_android_graphics_Matrix),<br />REG_JNI(register_android_graphics_Movie),<br />REG_JNI(register_android_graphics_NinePatch),<br />REG_JNI(register_android_graphics_Paint),<br />REG_JNI(register_android_graphics_Path),<br />REG_JNI(register_android_graphics_PathMeasure),<br />REG_JNI(register_android_graphics_PathEffect),<br />REG_JNI(register_android_graphics_Picture),<br />REG_JNI(register_android_graphics_PorterDuff),<br />REG_JNI(register_android_graphics_Rasterizer),<br />REG_JNI(register_android_graphics_Region),<br />REG_JNI(register_android_graphics_Shader),<br />REG_JNI(register_android_graphics_Typeface),<br />REG_JNI(register_android_graphics_Xfermode),<br />REG_JNI(register_com_android_internal_graphics_NativeUtils),<br />REG_JNI(register_android_database_CursorWindow),<br />REG_JNI(register_android_database_SQLiteDatabase),<br />REG_JNI(register_android_database_SQLiteDebug),<br />REG_JNI(register_android_database_SQLiteProgram),<br />REG_JNI(register_android_database_SQLiteQuery),<br />REG_JNI(register_android_database_SQLiteStatement),<br />REG_JNI(register_android_os_Debug),<br />REG_JNI(register_android_os_Exec),<br />REG_JNI(register_android_os_FileObserver),<br />REG_JNI(register_android_os_FileUtils),<br />REG_JNI(register_android_os_ParcelFileDescriptor),<br />REG_JNI(register_android_os_Power),<br />REG_JNI(register_android_os_StatFs),<br />REG_JNI(register_android_os_SystemProperties),<br />REG_JNI(register_android_os_UEventObserver),<br />REG_JNI(register_android_net_LocalSocketImpl),<br />REG_JNI(register_android_net_NetworkUtils),<br />REG_JNI(register_android_net_wifi_WifiManager),<br />REG_JNI(register_android_os_MemoryFile),<br />REG_JNI(register_com_android_internal_os_ZygoteInit),<br />REG_JNI(register_android_hardware_Camera),<br />REG_JNI(register_android_hardware_SensorManager),<br />REG_JNI(register_android_media_AudioRecord),<br />REG_JNI(register_android_media_AudioSystem),<br />REG_JNI(register_android_media_AudioTrack),<br />REG_JNI(register_android_media_JetPlayer),<br />REG_JNI(register_android_media_ToneGenerator),<br />REG_JNI(register_android_opengl_classes),<br />REG_JNI(register_android_bluetooth_Database),<br />REG_JNI(register_android_bluetooth_HeadsetBase),<br />REG_JNI(register_android_bluetooth_BluetoothAudioGateway),<br />REG_JNI(register_android_bluetooth_RfcommSocket),<br />REG_JNI(register_android_bluetooth_ScoSocket),<br />REG_JNI(register_android_server_BluetoothDeviceService),<br />REG_JNI(register_android_server_BluetoothEventLoop),<br />REG_JNI(register_android_server_BluetoothA2dpService),<br />REG_JNI(register_android_message_digest_sha1),<br />REG_JNI(register_android_ddm_DdmHandleNativeHeap),<br />REG_JNI(register_android_util_Base64),<br />REG_JNI(register_android_location_GpsLocationProvider),<br />};
這些初始化的native方法是java代碼與底層服務打交道的介面,因此我們必須初始化這些方法。
以app_process啟動java class的另外一個好處是它會初始化IBinder,這樣就可以在java代碼和jni代碼裡面接收IBinder訊息。