运用安卓模拟器发动flutter项目或许履行build apk --release --no-pub一直报了一个错误,百度了各大网页,对于安卓0经历开发的人来说仍是一脸的迷茫,所以今天记录一下,便于协助其他遇到相同问题的IOS开发者走出困境:

Execution failed for task ':app:processDebugMainManifest'.Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module @ffea291

一、报错内容

android studio点击debug main.dart爬虫按钮:

报错内容如下:

Launching lib/main.dart on sdk gphone64 arm64 in debug mode...
Running Gradle task 'assembleDebug'...
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:processDebugMainManifest'.
> Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module @ffea291
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 3s
Exception: Gradle task assembleDebug failed with exit code 1

二、flutter tools调试

经过运用flutter_tools调试

方法为: /packages/flutter_tools/lib/src/android/gradle.dart

Future<void> buildGradleApp({
  required FlutterProject project,
  required AndroidBuildInfo androidBuildInfo,
  required String target,
  required bool isBuildingBundle,
  required List<GradleHandledError> localGradleErrors,
  required bool configOnly,
  bool validateDeferredComponents = true,
  bool deferredComponentsEnabled = false,
  int retry = 0,
  @visibleForTesting int? maxRetries,
})

主要履行的功能为:

final String? javaHome = globals.androidSdk?.javaHome;
 exitCode = await _processUtils.stream(
   command,
   workingDirectory: project.android.hostAppGradleRoot.path,
   allowReentrantFlutter: true,
   environment: <String, String>{
     if (javaHome != null)
       AndroidSdk.javaHomeEnvironmentVariable: javaHome,
   },
   mapFunction: consumeLog,
 );

打印command 指令为

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

三、gradlew 指令解析

意思就是说履行flutter android工程下的 gradlew 指令 查看一下gradle是一个shell 脚本

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

在这个文件最终倒数第二行增加日志打印:

echo "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

从头履行 flutter run –debug

能够看到 经过flutter run –debug 运转安卓模拟器,本质上是需求履行gradle打包app指令 gradlew,格式化看的清楚一些:

/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
 -Xdock:name=Gradle 
 -Xdock:icon=/Users/axx/Desktop/carrier_project_name/android/media/gradle.icns 
 -Dorg.gradle.appname=gradlew 
 -classpath /Users/axx/Desktop/carrier_project_name/android/gradle/wrapper/gradle-wrapper.jar 
 org.gradle.wrapper.GradleWrapperMain 
 -q 
 -Ptarget-platform=android-arm64 
 -Ptarget=/Users/axx/Desktop/carrier_project_name/lib/main.dart 
 -Pbase-application-name=android.app.Application 
 -Pdart-defines=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC9jZGJlZGE3ODhhMjkzZmEyOTY2NWRjM2ZhM2Q2ZTYzYmQyMjFjYjBkLw== 
 -Pdart-obfuscation=false 
 -Ptrack-widget-creation=true 
 -Ptree-shake-icons=false 
 -Pfilesystem-scheme=org-dartlang-root 
 assembleDebug

意思就是经过java 来驱动发动app

四、错误分析

4.1 Android SDK & ndk 版别下载

cmd + ,翻开android studio 设置,下载Android sdk版别, ndk版别

android sdk 30,31,33版别 以及 ndk 21.1.6352462都是为了能尝试处理问题下载的版别

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

4.2 Project Structure设置

翻开android studio菜单,file 菜单,下面挑选Project Structure,翻开Project Structure设置窗框:

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

当时Module SDK版别设置: 挑选Module SDK设置为 API 33版别:

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

点击edit 挑选 android api 版别:

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

把不要的都删了, 这儿只留了 API 33的版别。

API language 没有改,默认啥样子就仍是什么样

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

4.3 android 模拟器设备管理Device Manager

从菜单挑选tools,点击 Device Manager

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

点击增加设备

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

挑选手机,挑选一个适宜尺度的模拟器:

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

这儿我下载了 api Level 33的 image镜像:

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

点击API33,完结设备增加:

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

点击发动按钮

这样就把安卓模拟器 模拟器发动好了

4.4 修改 build.gradle中的 kotlin_version 和 gradle版别

回到开始的报错:

FAILURE: Build failed with an exception.

  • What went wrong: Execution failed for task ‘:app:processDebugMainManifest’.

Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not “opens java.io” to unnamed module @ffea291

经过上面分析,是java履行指令出错了

which java

输出如下:

/usr/bin/java

履行 gradlew

java 指令为 Android Studio.app目录下的java 指令。

gradlew脚本内容如下:

echo "JAVA_HOME=$JAVA_HOME"
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

经过增加echo “JAVA_HOME=$JAVA_HOME”日志

JAVA_HOME=/Applications/Android Studio.app/Contents/jbr/Contents/Home

这个JAVA_HOME 在什么时候赋值了呢?

回到上面flutter tools发动指令的进程

final String? javaHome = globals.androidSdk?.javaHome;
exitCode = await _processUtils.stream(
  command,
  workingDirectory: project.android.hostAppGradleRoot.path,
  allowReentrantFlutter: true,
  environment: <String, String>{
    if (javaHome != null)
      AndroidSdk.javaHomeEnvironmentVariable: javaHome,
  },
  mapFunction: consumeLog,
);

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

则是在flutter tools履行时,经过android studio 的装置目录,自动动态获取的路径:

static const String javaHomeEnvironmentVariable = 'JAVA_HOME';

那么看看java 版别是多少:

/Applications/Android\ Studio.app/Contents/jbr/Contents/Home/bin/java --version

输出:

openjdk 17.0.6 2023-01-17
OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
OpenJDK 64-Bit Server VM (build 17.0.6+0-17.0.6b829.9-10027231, mixed mode)

到此,咱们知道咱们的 flutter run –debug的发动进程时经过java 履行gradlew 打包的进程

并且或许咱们的java 版别是17

参阅一下文章 www.kuazhi.com/post/425519…

最终 经过 修改 android/build.gradle 文件:

buildscript {
    ext.kotlin_version = '1.9.0'
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

旧的装备: ext.kotlin_version = ‘1.6.10’ classpath ‘com.android.tools.build:gradle:4.1.0’

修改为新的装备: ext.kotlin_version = ‘1.9.0’ classpath ‘com.android.tools.build:gradle:7.2.0’

这儿如果不修改 kotlin版别,则会报错:

FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugKotlin'.
> Compilation error. See log for more details
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 10s
┌─ Flutter Fix ──────────────────────────────────────────────────────────────────────────────┐
│ [!] Your project requires a newer version of the Kotlin Gradle plugin.                     │
│ Find the latest version on https://kotlinlang.org/docs/releases.html#release-details, then │
│ update /Users/axx/Desktop/carrier_project_name/android/build.gradle:                       │
│ ext.kotlin_version = '<latest-version>'                                                    │
└────────────────────────────────────────────────────────────────────────────────────────────┘
Exception: Gradle task assembleDebug failed with exit code 1

经过拜访 kotlinlang.org

看到Kotlin 当时 最新版别为1.9.0 ,所以修改为此装备。

从头运转,终于OK了。

记录一个iOS开发者使用flutter开发运行安卓模拟器的痛苦经历

总结

  • 安卓项目的发动是经过flutter tools找到 java_home 环境,即运用android studio app 程序下的java环境发动 gradlew 编译app。
  • flutter tools java bin path AndroidSdk.javaHomeEnvironmentVariable是经过本机装置的androd studio应用程序装置目录。为
 _processUtils.stream(
command,
workingDirectory: project.android.hostAppGradleRoot.path,
allowReentrantFlutter: true,
environment: <String, String>{
  if (javaHome != null)
    AndroidSdk.javaHomeEnvironmentVariable: javaHome,
},
mapFunction: consumeLog,
);
  • gradlew 为一个shell程序,发动指令为JAVA_HOME=/Applications/Android Studio.app/Contents/jbr/Contents/Home /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java -Xdock:name=Gradle -Xdock:icon=/Users/axx/Desktop/carrier_project_name/android/media/gradle.icns -Dorg.gradle.appname=gradlew -classpath /Users/axx/Desktop/carrier_project_name/android/gradle/wrapper/gradle-wrapper.jar org.gradle.wrapper.GradleWrapperMain -q -Ptarget-platform=android-arm64 -Ptarget=/Users/axx/Desktop/carrier_project_name/lib/main.dart -Pbase-application-name=android.app.Application -Pdart-defines=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC9jZGJlZGE3ODhhMjkzZmEyOTY2NWRjM2ZhM2Q2ZTYzYmQyMjFjYjBkLw== -Pdart-obfuscation=false -Ptrack-widget-creation=true -Ptree-shake-icons=false -Pfilesystem-scheme=org-dartlang-root assembleDebug

  • 我的安卓stuio版别是Android Studio Giraffe | 2022.3.1则经过修改build.gradle装备文件的com.android.tools.build:gradle版别和kotlin_version版别处理 java 版别不匹配问题,即可成功运转项目或许打包apk