尝试运行“ionic cordova run --emulator”时,在com.android.prefs.AndroidLocation.getAvdFolder()上获取NoSuchMethodError异常

时间:2017-05-13 04:30:09

标签: android cordova ionic-framework emulation

我刚升级了我的cordova和离子(npm upgrade -g cordova ionic),现在当我运行“ionic cordova run --emulator”时,我收到以下错误信息:

线程“main”中的异常java.lang.NoSuchMethodError:com.android.prefs.AndroidLocation.getAvdFolder()Ljava / lang / String;

构建成功,它似乎不想启动模拟器。

非常感谢任何帮助。

以下是成功构建消息后的日志结束:

建立成功

总时间:5.135秒 建立以下apk(s):     /Users/lesbuchanan/source/personal/sandbox/mobile/ionic/phone-vow/platforms/android/build/outputs/apk/android-debug.apk

ANDROID_HOME = /用户/ lesbuchanan /库/ Android设备/ SDK / JAVA_HOME = /图书馆/的Java / JavaVirtualMachines / jdk1.8.0_112.jdk /内容/首页 错误:avdmanager:命令失败,退出代码1错误输出: 线程“main”中的异常java.lang.NoSuchMethodError:com.android.prefs.AndroidLocation.getAvdFolder()Ljava / lang / String;     在com.android.sdklib.internal.avd.AvdManager.getInstance(AvdManager.java:380)     在com.android.sdklib.tool.AvdManagerCli.getAvdManager(AvdManagerCli.java:338)     在com.android.sdklib.tool.AvdManagerCli.displayAvdList(AvdManagerCli.java:516)     在com.android.sdklib.tool.AvdManagerCli.doAction(AvdManagerCli.java:355)     在com.android.sdklib.tool.AvdManagerCli.run(AvdManagerCli.java:203)     在com.android.sdklib.tool.AvdManagerCli.main(AvdManagerCli.java:193)

[错误] Cordova遇到错误。         您可以通过直接运行上面的Cordova命令获得更多洞察力。

[错误]运行cordova时发生错误运行android --emulator(退出代码1)。输入代码

2 个答案:

答案 0 :(得分:4)

事实证明,我刚刚使用Android Studio来更新SDK工具。转到首选项 - >外观&行为 - >系统设置 - > Android SDK,然后点击SDK工具标签。我更新了以下软件包:

  • Android SDK Build-Tools
  • Android模拟器
  • Android SDK平台工具
  • Android SDK工具
  • Intel x86仿真器加速器
  • 支持存储库 - > Android支持存储库
  • 支持存储库 - > Google存储库

老实说,我不确定哪个包解决了我的问题,但我想同时更新所有这些包都是个好主意。希望这有助于某人。

答案 1 :(得分:1)

tl;dr 您遇到了 jar 地狱问题,可能是由 Android SDK 修补程序引起的。唯一对我有用的是删除 ANDROID_HOME 目录中的所有内容并使用 IntelliJ IDEA 的 Android SDK 管理器(Android Studio 构建在其之上)并重新安装 Android SDK。请注意,更新 Android SDK tools 可能会起作用,因为它在 Les Buchanan's answer 中起作用,但对于通常由 SDK 修补程序本身引起的问题来说,它更像是一个幸运的修复。

详细解释: Ionic、Cordova 等建立在 Android SDK 提供的基础之上。 cordova run --emulator 调用 avdmanager 是因为您首先需要一个 Android 虚拟设备进行模拟。所以我直接运行了它,但仍然遇到了 OP 的问题,显然从可能的原因中消除了 cordovaionic

$ $ANDROID_HOME/tools/bin/avdmanager.bat
Exception in thread "main" java.lang.NoSuchMethodError: com.android.prefs.AndroidLocation.getAvdFolder()Ljava/lang/String;
        at com.android.sdklib.tool.AvdManagerCli.init(AvdManagerCli.java:278)
        at com.android.sdklib.tool.AvdManagerCli.run(AvdManagerCli.java:210)
        at com.android.sdklib.tool.AvdManagerCli.main(AvdManagerCli.java:200)

如果您查看 andmanager.bat 文件,您会看到它在第 68-69 行附近调用了 AvdManagerCli 主类:

@rem Execute avdmanager
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %AVDMANAGER_OPTS%  -classpath "%CLASSPATH%" com.android.sdklib.tool.AvdManagerCli %CMD_LINE_ARGS%

它上面的一行设置了 CLASSPATH 变量,其中包括以下条目:APP_HOME%\lib\common-26.0.0-dev.jar。如果你看里面,例如解压并打开 com.android.prefs.AndroidLocation 类,您会注意到 getAvdFolder 方法存在。那它为什么avdmanager抱怨它?当我过去遇到过类似问题时,这通常意味着类路径中有 2 个或更多版本的此类和/或从不正确且经常过时的 jar 文件加载该类。

所以,我想看看这个类加载了哪个jar。回到第 68-69 行的 avdmanager.bat,添加了 -verbose:class 标志,其中 AvdManagerCli 是用上面的 java 命令调用的,并再次运行 avdmanager.bat,这次显示我正在加载的类:

[Opened C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.io.Serializable from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.lang.Comparable from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
...
...
many
...
entries
...
ahead
...
[Loaded com.android.sdklib.util.CommandLineParser$Arg from file:/C:/Users/sburcea/AppData/Local/Android/Sdk/tools/lib/sdklib-26.0.0-dev.jar]
[Loaded com.android.prefs.AndroidLocation from file:/C:/Users/sburcea/AppData/Local/Android/Sdk/tools/lib/common.jar]
Exception in thread "main" [Loaded java.lang.Throwable$PrintStreamOrWriter from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.lang.Throwable$WrappedPrintStream from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.util.IdentityHashMap from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
[Loaded java.util.IdentityHashMap$KeySet from C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar]
java.lang.NoSuchMethodError: com.android.prefs.AndroidLocation.getAvdFolder()Ljava/lang/String;
        at com.android.sdklib.tool.AvdManagerCli.init(AvdManagerCli.java:278)
        at com.android.sdklib.tool.AvdManagerCli.run(AvdManagerCli.java:210)
        at com.android.sdklib.tool.AvdManagerCli.main(AvdManagerCli.java:200)

啊哈!所以 com.android.prefs.AndroidLocation 是从 ANDROID_HOME/tools/lib/common.jar 加载的,它甚至没有在类路径中提到!查看 ANDROID_HOME\lib\common.jar 内部发现它包含 com.android.prefs.AndroidLocation 类,但它没有 #getAvdFolder。这可能是我在我的机器上安装的旧 SDK 的遗留物。无论如何,我需要清理并删除文件夹并重新安装Android SDK,问题就消失了。我仍然想知道哪个 jar 加载了 com.android.prefs.AndroidLocation 类并且我已将 -verbose:class 添加回我的 avdmanager.bat

$ /c/Users/sburcea/AppData/Local/Android/Sdk/tools/bin/avdmanager.bat | grep AndroidLocation
[Loaded com.android.prefs.AndroidLocation$AndroidLocationException from file:/C:/Users/sburcea/AppData/Local/Android/Sdk/tools/lib/common-26.0.0-dev.jar]
[Loaded com.android.prefs.AndroidLocation from file:/C:/Users/sburcea/AppData/Local/Android/Sdk/tools/lib/common-26.0.0-dev.jar]
[Loaded com.android.prefs.AndroidLocation$Global from file:/C:/Users/sburcea/AppData/Local/Android/Sdk/tools/lib/common-26.0.0-dev.jar]