app_process: 启动java进程(1)

涉及源码

android-8.0.0_r1\frameworks\base\cmds\app_process
android- 8.0.0_r1\frameworks\base\core\jni\AndroidRuntime.cpp

概述

app_process是Android系统中一个重要的编译出来的可执行文件。该执行文件在开机过程中负责启动Android核心的进程zygote和system_server。
app_process也可以用来运行可执行的java程序。

主要流程

app_process可执行文件的核心文件是

frameworks\base\cmds\app_process\app_main.cpp
frameworks\base\core\jni\AndroidRuntime.cpp

在这里插入图片描述

  1. 创建运行时类对象(AndroidRuntime类)
  2. 图像模块底层初始化
  3. app_process命令的参数解析
  4. 使用AndroidRuntime对象启动java进程。注意: 启动的java进程有两种类型:
    4.1. 不指定类名和应用名,按照系统默认配置,启动zygote和system_server
    4.2 按照指定的类名和应用,查找其中的main函数作为入口,运行java程序
  5. 运行java程序。运行java程序,并不是直接执行指定程序的main函数,而是在中间加了一层,通过ZygoteInit或RuntimeInit来运行最终要运行的java可执行程序
// file: frameworks\base\cmds\app_process\app_main.cpp
// function: main
if (zygote) {
		/* 
		启动zygote和system_server.在参数解析不能体现启动system_server是调用ZygoteInit,
		在更深层的代码追踪,会发现system_server通过ZygoteInit启动。也即启动system_server,
		zygote一定为true,除非通过命令直接启动system_server.此处主要呈现的是Android系统启动过程.
		*/
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
    	// 启动其他
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }

重点说明AndroidRuntime start函数

在AndroidRuntime的start中,执行了运行java程序核心步骤:

  1. 创建虚拟机
    在创建虚拟机代码中可以看到初始化很多数据,了解虚拟用到的参数,可以根据设备特性,更优的配置参数和满足产品及用户需求
// file: frameworks\base\core\jni\AndroidRuntime.cpp
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{
	// 1.初始化参数
    JavaVMInitArgs initArgs;
    char propBuf[PROPERTY_VALUE_MAX];
    char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];
    char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
    char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
    char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
    char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
    char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
    char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
    char usejitOptsBuf[sizeof("-Xusejit:")-1 + PROPERTY_VALUE_MAX];
    char jitmaxsizeOptsBuf[sizeof("-Xjitmaxsize:")-1 + PROPERTY_VALUE_MAX];
    ...
    char dex2oatThreadsImageBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX];
    char dex2oat_isa_variant_key[PROPERTY_KEY_MAX];
    char dex2oat_isa_variant[sizeof("--instruction-set-variant=") -1 + PROPERTY_VALUE_MAX];
    char dex2oat_isa_features_key[PROPERTY_KEY_MAX];
    char dex2oat_isa_features[sizeof("--instruction-set-features=") -1 + PROPERTY_VALUE_MAX];
    char dex2oatFlagsBuf[PROPERTY_VALUE_MAX];
    char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX];
    char extraOptsBuf[PROPERTY_VALUE_MAX];
    char voldDecryptBuf[PROPERTY_VALUE_MAX];
    ...
    // 2.真正创建虚拟机
     /*
     * Initialize the VM.
     *
     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     * If this call succeeds, the VM is ready, and we can start issuing
     * JNI calls.
     */
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        return -1;
    }

    return 0;
}
  1. 针对每个虚拟机,注册运行时用到的jni接口
    在Android系统中做垂直开发,避免不了增加jni接口。添加jni接口有两种方式:
    2.1 jni接口继承到系统运行时库中
    2.2 单独编译一个动态库,在运行的java程序中,通过调用System.loadLibrary加载动态库

此处是加载系统运行时库

// file: frameworks\base\core\jni\AndroidRuntime.cpp
/*
 * Register android native functions with the VM.
 */
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    ATRACE_NAME("RegisterAndroidNatives");
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     */
    // 创建和java环境关联的线程
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    ALOGV("--- registering native functions ---\n");

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);

	// 注册jni接口:多个模块的
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}

注意变量gRegJNI

// file: frameworks\base\core\jni\AndroidRuntime.cpp
// array是传入的gRegJNI
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
    for (size_t i = 0; i < count; i++) {
        if (array[i].mProc(env) < 0) {
#ifndef NDEBUG
            ALOGD("----------!!! %s failed to load\n", array[i].mName);
#endif
            return -1;
        }
    }
    return 0;
}

// 包含了Android系统中各模块的jni
static const RegJNIRec gRegJNI[] = {
    REG_JNI(register_com_android_internal_os_RuntimeInit),
    REG_JNI(register_com_android_internal_os_ZygoteInit),
    ...
    REG_JNI(register_android_os_Binder),
    REG_JNI(register_android_os_Parcel),
    REG_JNI(register_android_os_HwBinder),
    REG_JNI(register_android_os_HwBlob),
    ...
    REG_JNI(register_android_graphics_Canvas),
    REG_JNI(register_android_graphics_Graphics),
    ...
    REG_JNI(register_android_hardware_Camera),
    REG_JNI(register_android_hardware_camera2_CameraMetadata),    		    REG_JNI(register_android_hardware_camera2_legacy_LegacyCameraDevice),
    ...
    REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
    REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
    REG_JNI(register_com_android_internal_os_FuseAppLoop),
};
  1. 查找入口函数main,然后运行java程序
    在实际运行过程会创建独立进程,这个在后面的细节部分展现。
// file: frameworks\base\core\jni\AndroidRuntime.cpp
// function: start函数
/*
    * Start VM.  This thread becomes the main thread of the VM, and will
    * not return until the VM exits.
    */
   char* slashClassName = toSlashClassName(className);
   jclass startClass = env->FindClass(slashClassName);
   if (startClass == NULL) {
       ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
       /* keep going */
   } else {
   	// 查找main函数
       jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
           "([Ljava/lang/String;)V");
       if (startMeth == NULL) {
           ALOGE("JavaVM unable to find main() in '%s'\n", className);
           /* keep going */
       } else {
       	// 执行main函数
           env->CallStaticVoidMethod(startClass, startMeth, strArray);
           }
      }
   ...
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
app_process 是一个在 Android 系统中运行的进程,它是用来运行 Java 代码的主要组件之一。通过 app_process,Android 系统可以加载和执行 Java 类,并且允许开发者编写各种类型的 Android 应用程序。 app_process 通常被用于运行 Android 应用的主线程,它负责初始化应用程序的一些重要组件,例如 Activity 和 Service。在应用程序启动时,app_process 会进行一系列的初始化工作,包括创建虚拟机、加载系统类库、注册应用程序的生命周期回调等。 在 app_process 中,Java 代码会被编译成 Dalvik 字节码,然后由 Dalvik 虚拟机进行解释执行。Dalvik 虚拟机是专门为 Android 设计的一种虚拟机,相较于传统的 JVM,它对内存占用和性能有着优化。因此,app_process 运行的 Java 代码相对于在传统的 JVM 上运行的 Java 代码来说,更加适合在资源受限的移动设备上执行。 在 app_process 运行的过程中,它与系统的其他组件和服务进行交互,与底层的 Android 系统进行通信,以实现应用程序所需的各种功能和特性。同时,app_process 也负责管理应用程序的内存和进程的生命周期,以确保应用程序能够正常运行,并且不会对系统的稳定性和性能产生过大的影响。 总之,app_process 是 Android 系统中负责运行 Java 代码的关键组件,它扮演了应用程序与系统之间的桥梁角色,确保应用程序能够在 Android 系统上正确运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值