首先cmd切换到android-sdk-windows\tools\lib,找到find_java.bat
打开回显:rem @echo off,再运行find_java.bat,若输出的set java_exe=同jdk安装路径不符,则需要检查环境变量JAVA_HOME和PATH中java.exe是否设置正确,其逻辑在于android/platform/sdk/find_java/src/source/find_java_lib.cpp中的函数findJavaInEnvPath:
View Code// Search java.exe in the environment int findJavaInEnvPath(CPath *outJavaPath, bool isJdk, int minVersion) { SetLastError(0); const char* envPath = getenv("JAVA_HOME"); if (envPath != NULL) { CPath p(envPath); if (!isJdk || isJdkPath(p)) { int v = checkBinPath(&p); if (v >= minVersion) { if (gIsDebug) { fprintf(stderr, "Java %d found via JAVA_HOME: %s\n", v, p.cstr()); } *outJavaPath = p; // As an optimization for runtime, if we find a suitable java // version in JAVA_HOME we won't waste time looking at the PATH. return v; } } } int currVersion = 0; envPath = getenv("PATH"); if (!envPath) return currVersion; // Otherwise look at the entries in the current path. // If we find more than one, keep the one with the highest version. CArray<CString> *paths = CString(envPath).split(';'); for(int i = 0; i < paths->size(); i++) { CPath p((*paths)[i].cstr()); if (isJdk && !isJdkPath(p)) { continue; } int v = checkPath(&p); if (v >= minVersion && v > currVersion) { if (gIsDebug) { fprintf(stderr, "Java %d found via env PATH: %s\n", v, p.cstr()); } currVersion = v; *outJavaPath = p; } } delete paths; return currVersion; }
可看到其逻辑是在环境变量中先查找JAVA_HOME,若没有则再查找PATH中最高版本的java.exe,当然java.exe的版本最小为6.1。
若环境变量中java.exe设置无误,则检查批处理find_java.bat是否有误,这是因为SDK Manager.exe源码android/platform/sdk/sdklauncher/src/source/sdklauncher.c显示其是调用android-sdk-windows\tools\android.bat
View Codeint sdk_launcher() { int result = 0; STARTUPINFO startup; PROCESS_INFORMATION pinfo; CHAR program_dir[MAX_PATH]; int ret, pos; ZeroMemory(&pinfo, sizeof(pinfo)); ZeroMemory(&startup, sizeof(startup)); startup.cb = sizeof(startup); startup.dwFlags = STARTF_USESHOWWINDOW; startup.wShowWindow = SW_HIDE|SW_MINIMIZE; /* get path of current program, to switch dirs here when executing the command. */ ret = GetModuleFileName(NULL, program_dir, sizeof(program_dir)); if (ret == 0) { display_error("Failed to get program's filename:"); result = 1; } else { /* Remove the last segment to keep only the directory. */ pos = ret - 1; while (pos > 0 && program_dir[pos] != '\\') { --pos; } program_dir[pos] = 0; } if (!result) { dprintf("Program dir: %s\n", program_dir); // SDK Manager.exe is installed by the Windows Installer just below // the tools directory and needs to access tools\android.bat ret = CreateProcess( NULL, /* program path */ "tools\\android.bat sdk", /* command-line */ NULL, /* process handle is not inheritable */ NULL, /* thread handle is not inheritable */ TRUE, /* yes, inherit some handles */ CREATE_NO_WINDOW, /* we don't want a console */ NULL, /* use parent's environment block */ program_dir, /* use parent's starting directory */ &startup, /* startup info, i.e. std handles */ &pinfo); if (!ret) { dprintf("CreateProcess returned %d\n", ret); // In the ADT bundle, SDK Manager.exe is located in the sdk folder // and needs to access sdk\tools\android.bat ret = CreateProcess( NULL, /* program path */ "sdk\\tools\\android.bat sdk", /* command-line */ NULL, /* process handle is not inheritable */ NULL, /* thread handle is not inheritable */ TRUE, /* yes, inherit some handles */ CREATE_NO_WINDOW, /* we don't want a console */ NULL, /* use parent's environment block */ program_dir, /* use parent's starting directory */ &startup, /* startup info, i.e. std handles */ &pinfo); } dprintf("CreateProcess returned %d\n", ret); if (!ret) { display_error("Failed to execute tools\\android.bat:"); result = 1; } } dprintf("Cleanup.\n"); return result; }