问题描述 投票:0回答:1
我需要在 Android Studio 模拟器上运行一个项目,但模拟器的 JVM 缺少一个方法。

之前在物理设备(API 31 - 33)上测试成功的源代码,现在在 AVD Android Studio 模拟器(Pixel 4 API 34)上测试时,会出现异常:

FATAL EXCEPTION: main Process: com.org.project, PID: 11295 java.lang.NoSuchMethodError: No virtual method indent(I)Ljava/lang/String; in class Ljava/lang/String; or its super classes (declaration of 'java.lang.String' appears in /apex/com.android.art/javalib/core-oj.jar) at
这些是模拟器属性:

Properties avd.ini.displayname Pixel 5 API 33 2 avd.ini.encoding UTF-8 AvdId Pixel_5_API_33_2 disk.dataPartition.size 6442450944 fastboot.chosenSnapshotFile fastboot.forceChosenSnapshotBoot no fastboot.forceColdBoot no fastboot.forceFastBoot yes hw.accelerometer yes hw.arc false hw.audioInput yes hw.battery yes hw.camera.back virtualscene hw.camera.front emulated hw.cpu.ncore 4 hw.device.hash2 MD5:3274126e0242a0d86339850416b0ce34 hw.device.manufacturer Google hw.device.name pixel_5 hw.dPad no hw.gps yes hw.gpu.enabled yes hw.gpu.mode auto hw.initialOrientation Portrait hw.keyboard yes hw.lcd.density 440 hw.lcd.height 2340 hw.lcd.width 1080 hw.mainKeys no hw.ramSize 1536 hw.sdCard yes hw.sensors.orientation yes hw.sensors.proximity yes hw.trackBall no image.androidVersion.api 33 image.sysdir.1 system-images\android-33\google_apis\x86_64\ PlayStore.enabled false runtime.network.latency none runtime.network.speed full showDeviceFrame yes skin.dynamic yes tag.display Google APIs tag.id google_apis vm.heapSize 228
在项目内查看Java源代码时,方法就在那里:

/** * a comment explaining the method... * @since 12 */ public String indent(int n) { if (isEmpty()) { return ""; } Stream<String> stream = lines(); if (n > 0) { final String spaces = " ".repeat(n); stream = stream.map(s -> spaces + s); } else if (n == Integer.MIN_VALUE) { stream = stream.map(s -> s.stripLeading()); } else if (n < 0) { stream = stream.map(s -> s.substring(Math.min(-n, s.indexOfNonWhitespace()))); } return stream.collect(Collectors.joining("\n", "", "\n")); }
据我所知,Android 对标准库的专有使用在 Java 11 时停止了。
从那时起,添加了额外的 Gradle/编译/插件选项,以利用属于 11 以上版本的 Java 工具。

这些是本项目中使用的配置:

plugins { id 'com.android.application' id 'kotlin-android' id 'com.google.gms.google-services' } android { namespace 'com.me.myproject' compileSdk 34 defaultConfig { applicationId "com.me.myproject" minSdkVersion 26 targetSdkVersion 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = '17' } } dependencies { testImplementation 'junit:junit:4.13.2' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.3' // << This is the main plugin in charge of compatibility. } apply plugin: 'kotlin-android'
此特定模拟器正在使用 Android Studio 的计算机上运行,该 Android Studio 管理与 IDE 捆绑在一起的 Java 库。

在我看来,Android Studio(和其他 IntelliJ 产品)将此 JDK 分配给在此 IDE 中打开的每个项目。

这意味着 Gradle、编译器甚至 IDE 上使用的 Java 运行时都使用“合成”JAVA_HOME,而且也是由 IDE 配置分配的合成 Gradle。 这样 IDE 执行的任何操作都会作用于这些自动生成的全局变量,即为每个项目分配一个变量。

这使得诸如

检查 Java 版本运行 Gradle 命令之类的任务变得非常困难,因为人们无法使用 Windows 的 CLI,甚至无法使用 Android Studio 本身在“终端”选项卡下提供的 CLI...它使用默认的 Windows PowerShell。

这就是为什么我发现 Gradle 文档几乎毫无意义,因为该文档是在假设机器中安装了完整的 Gradle 程序的情况下编写的。

Android Studio有一个Gradle插件,它有一个CLI,这个CLI(有点隐藏)是唯一可以处理这些自动生成的变量的,所以,任何需要在Gradle上运行的任务都需要通过这个来完成CLI.

对于与 JVM 所需的任何交互,我发现与其有效交互的唯一方法是通过一些 UI 面板。

其中一个位于“项目结构”中,另一个位于 IDE“设置”中,另一个通过右键单击测试类来定义“VM 选项”。

    我遇到的一个更困难的问题是为 javadoc.exe 定义一个特定的 JDK (17),它修复了属于 javadoc 16 的错误,这是在另一个具有完全相同类型的项目特定变量的项目中。 这个问题已通过一些常规脚本魔法在
  • build.gradle
     文件中修复。
但是这个问题与编译阶段无关,甚至与代码本身无关,它似乎是 AVD 独有的。

对于在模拟器的 ART(Android 运行时)中运行的 JVM,没有提供让您选择特定 JDK 的选项。

我认为答案可能在于其中一些配置,也许答案在于某些

build.gradle

配置。

java android android-virtual-device nosuchmethoderror android-runtime
1个回答
0
投票
现已在 AVD Android Studio 模拟器(Pixel 4 API 34)上进行测试

这与您所显示的模拟器属性不符。特别是,这些属性表明 API 级别是 33,而不是 34:

avd.ini.displayname Pixel 5 API 33 2 AvdId Pixel_5_API_33_2 image.androidVersion.api 33 image.sysdir.1 system-images\android-33\google_apis\x86_64\

indent()

 已添加到 API 级别 34 的 Android SDK 中。我不希望在您的模拟器映像上找到 
indent()

© www.soinside.com 2019 - 2024. All rights reserved.