Shutting down VM
786 void AndroidRuntime::start(const char* className, const char* options) 787 { 788 ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n", 789 className != NULL ? className : "(unknown)"); 790 791 blockSigpipe(); 792 793 /* 794 * 'startSystemServer == true' means runtime is obsolete and not run from 795 * init.rc anymore, so we print out the boot start event here. 796 */ 797 if (strcmp(options, "start-system-server") == 0) { 798 /* track our progress through the boot sequence */ 799 const int LOG_BOOT_PROGRESS_START = 3000; 800 LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, 801 ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 802 } 803 804 const char* rootDir = getenv("ANDROID_ROOT"); 805 if (rootDir == NULL) { 806 rootDir = "/system"; 807 if (!hasDir("/system")) { 808 LOG_FATAL("No root directory specified, and /android does not exist."); 809 return; 810 } 811 setenv("ANDROID_ROOT", rootDir, 1); 812 } 813 814 //const char* kernelHack = getenv("LD_ASSUME_KERNEL"); 815 //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); 816 817 /* start the virtual machine */ 818 JNIEnv* env; 819 if (startVm(&mJavaVM, &env) != 0) { 820 return; 821 } 822 onVmCreated(env); 823 824 /* 825 * Register android functions. 826 */ 827 if (startReg(env) < 0) { 828 ALOGE("Unable to register all android natives\n"); 829 return; 830 } 831 832 /* 833 * We want to call main() with a String array with arguments in it. 834 * At present we have two arguments, the class name and an option string. 835 * Create an array to hold them. 836 */ 837 jclass stringClass; 838 jobjectArray strArray; 839 jstring classNameStr; 840 jstring optionsStr; 841 842 stringClass = env->FindClass("java/lang/String"); 843 assert(stringClass != NULL); 844 strArray = env->NewObjectArray(2, stringClass, NULL); 845 assert(strArray != NULL); 846 classNameStr = env->NewStringUTF(className); 847 assert(classNameStr != NULL); 848 env->SetObjectArrayElement(strArray, 0, classNameStr); 849 optionsStr = env->NewStringUTF(options); 850 env->SetObjectArrayElement(strArray, 1, optionsStr); 851 852 /* 853 * Start VM. This thread becomes the main thread of the VM, and will 854 * not return until the VM exits. 855 */ 856 char* slashClassName = toSlashClassName(className); 857 jclass startClass = env->FindClass(slashClassName); 858 if (startClass == NULL) { 859 ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); 860 /* keep going */ 861 } else { 862 jmethodID startMeth = env->GetStaticMethodID(startClass, "main", 863 "([Ljava/lang/String;)V"); 864 if (startMeth == NULL) { 865 ALOGE("JavaVM unable to find main() in '%s'\n", className); 866 /* keep going */ 867 } else { 868 env->CallStaticVoidMethod(startClass, startMeth, strArray); 869 870 #if 0 871 if (env->ExceptionCheck()) 872 threadExitUncaughtException(env); 873 #endif 874 } 875 } 876 free(slashClassName); 877 878 ALOGD("Shutting down VM\n"); 879 if (mJavaVM->DetachCurrentThread() != JNI_OK) 880 ALOGW("Warning: unable to detach main thread\n"); 881 if (mJavaVM->DestroyJavaVM() != 0) 882 ALOGW("Warning: VM did not shut down cleanly\n"); 883 }>