在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

arg = argv[i++];

if(0 == strcmp("--zygote", arg)) {

boolstartSystemServer = (i

strcmp(argv[i], "--start-system-server") == 0 :false;

setArgv0(argv0, "zygote");

set_process_name("zygote");

runtime.start("com.android.internal.os.ZygoteInit",

startSystemServer);

} else{

set_process_name(argv0);

runtime.mClassName = arg;

// Remainder of args get passed to startup class main()

runtime.mArgC = argc-i;

runtime.mArgV = argv+i;

LOGV("App process is starting with pid=%d, class=%s.\n",

getpid(), runtime.getClassName());

runtime.start();

}

}

从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行):

staticconstRegJNIRec gRegJNI[] = {

REG_JNI(register_android_debug_JNITest),

REG_JNI(register_com_android_internal_os_RuntimeInit),

REG_JNI(register_android_os_SystemClock),

REG_JNI(register_android_util_EventLog),

REG_JNI(register_android_util_Log),

REG_JNI(register_android_util_FloatMath),

REG_JNI(register_android_text_format_Time),

REG_JNI(register_android_pim_EventRecurrence),

REG_JNI(register_android_content_AssetManager),

REG_JNI(register_android_content_StringBlock),

REG_JNI(register_android_content_XmlBlock),

REG_JNI(register_android_emoji_EmojiFactory),

REG_JNI(register_android_security_Md5MessageDigest),

REG_JNI(register_android_text_AndroidCharacter),

REG_JNI(register_android_text_KeyCharacterMap),

REG_JNI(register_android_os_Process),

REG_JNI(register_android_os_Binder),

REG_JNI(register_android_os_Hardware),

REG_JNI(register_android_view_Display),

REG_JNI(register_android_nio_utils),

REG_JNI(register_android_graphics_PixelFormat),

REG_JNI(register_android_graphics_Graphics),

REG_JNI(register_android_view_Surface),

REG_JNI(register_android_view_ViewRoot),

REG_JNI(register_com_google_android_gles_jni_EGLImpl),

REG_JNI(register_com_google_android_gles_jni_GLImpl),

REG_JNI(register_android_graphics_Bitmap),

REG_JNI(register_android_graphics_BitmapFactory),

REG_JNI(register_android_graphics_Camera),

REG_JNI(register_android_graphics_Canvas),

REG_JNI(register_android_graphics_ColorFilter),

REG_JNI(register_android_graphics_DrawFilter),

REG_JNI(register_android_graphics_Interpolator),

REG_JNI(register_android_graphics_LayerRasterizer),

REG_JNI(register_android_graphics_MaskFilter),

REG_JNI(register_android_graphics_Matrix),

REG_JNI(register_android_graphics_Movie),

REG_JNI(register_android_graphics_NinePatch),

REG_JNI(register_android_graphics_Paint),

REG_JNI(register_android_graphics_Path),

REG_JNI(register_android_graphics_PathMeasure),

REG_JNI(register_android_graphics_PathEffect),

REG_JNI(register_android_graphics_Picture),

REG_JNI(register_android_graphics_PorterDuff),

REG_JNI(register_android_graphics_Rasterizer),

REG_JNI(register_android_graphics_Region),

REG_JNI(register_android_graphics_Shader),

REG_JNI(register_android_graphics_Typeface),

REG_JNI(register_android_graphics_Xfermode),

REG_JNI(register_com_android_internal_graphics_NativeUtils),

REG_JNI(register_android_database_CursorWindow),

REG_JNI(register_android_database_SQLiteDatabase),

REG_JNI(register_android_database_SQLiteDebug),

REG_JNI(register_android_database_SQLiteProgram),

REG_JNI(register_android_database_SQLiteQuery),

REG_JNI(register_android_database_SQLiteStatement),

REG_JNI(register_android_os_Debug),

REG_JNI(register_android_os_Exec),

REG_JNI(register_android_os_FileObserver),

REG_JNI(register_android_os_FileUtils),

REG_JNI(register_android_os_ParcelFileDescriptor),

REG_JNI(register_android_os_Power),

REG_JNI(register_android_os_StatFs),

REG_JNI(register_android_os_SystemProperties),

REG_JNI(register_android_os_UEventObserver),

REG_JNI(register_android_net_LocalSocketImpl),

REG_JNI(register_android_net_NetworkUtils),

REG_JNI(register_android_net_wifi_WifiManager),

REG_JNI(register_android_os_MemoryFile),

REG_JNI(register_com_android_internal_os_ZygoteInit),

REG_JNI(register_android_hardware_Camera),

REG_JNI(register_android_hardware_SensorManager),

REG_JNI(register_android_media_AudioRecord),

REG_JNI(register_android_media_AudioSystem),

REG_JNI(register_android_media_AudioTrack),

REG_JNI(register_android_media_JetPlayer),

REG_JNI(register_android_media_ToneGenerator),

REG_JNI(register_android_opengl_classes),

REG_JNI(register_android_bluetooth_Database),

REG_JNI(register_android_bluetooth_HeadsetBase),

REG_JNI(register_android_bluetooth_BluetoothAudioGateway),

REG_JNI(register_android_bluetooth_RfcommSocket),

REG_JNI(register_android_bluetooth_ScoSocket),

REG_JNI(register_android_server_BluetoothDeviceService),

REG_JNI(register_android_server_BluetoothEventLoop),

REG_JNI(register_android_server_BluetoothA2dpService),

REG_JNI(register_android_message_digest_sha1),

REG_JNI(register_android_ddm_DdmHandleNativeHeap),

REG_JNI(register_android_util_Base64),

REG_JNI(register_android_location_GpsLocationProvider),

};

这些初始化的native方法是java代码与底层服务打交道的接口,因此我们必须初始化这些方法。

以app_process启动java class的另外一个好处是它会初始化IBinder,这样就可以在java代码和jni代码里面接收IBinder消息。

原文链接:

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐