使用安卓模拟器启动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.orgBUILD FAILED in 3sException: Gradle task assembleDebug failed with exit code 1Launching 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 1Launching 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,})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, })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,);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, );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 命令为
三、gradlew 命令解析
意思就是说执行flutter android工程下的 gradlew 命令
查看一下gradle是一个shell 脚本
在这个文件最后倒数第二行添加日志打印:
echo "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"echo "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"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.jarorg.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-rootassembleDebug/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/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都是为了能尝试解决问题下载的版本
4.2 Project Structure设置
打开android studio菜单,file 菜单,下面选择Project Structure,打开Project Structure设置窗框:
当前Module SDK版本设置:
选择Module SDK设置为 API 33版本:
点击edit 选择 android api 版本:
把不要的都删了, 这里只留了 API 33的版本。
API language 没有改,默认啥样子就还是什么样
4.3 android 模拟器设备管理Device Manager
从菜单选择tools,点击 Device Manager
点击添加设备
选择手机,选择一个合适尺寸的模拟器:
这里我下载了 api Level 33的 image镜像:
点击API33,完成设备添加:
点击启动按钮
这样就把安卓模拟器 模拟器启动好了
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 javawhich javawhich java
输出如下:
/usr/bin/java/usr/bin/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" ] ; thenif [ -x "$JAVA_HOME/jre/sh/java" ] ; then# IBM's JDK on AIX uses strange locations for the executablesJAVACMD="$JAVA_HOME/jre/sh/java"elseJAVACMD="$JAVA_HOME/bin/java"fiif [ ! -x "$JAVACMD" ] ; thendie "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOMEPlease set the JAVA_HOME variable in your environment to match thelocation of your Java installation."fielseJAVACMD="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 thelocation of your Java installation."fiecho "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." fiecho "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,);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, );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, );
则是在flutter tools执行时,通过android studio 的安装目录,自动动态获取的路径:
static const String javaHomeEnvironmentVariable = 'JAVA_HOME';static const String javaHomeEnvironmentVariable = 'JAVA_HOME';static const String javaHomeEnvironmentVariable = 'JAVA_HOME';
那么看看java 版本是多少:
/Applications/Android\ Studio.app/Contents/jbr/Contents/Home/bin/java --version/Applications/Android\ Studio.app/Contents/jbr/Contents/Home/bin/java --version/Applications/Android\ Studio.app/Contents/jbr/Contents/Home/bin/java --version
输出:
openjdk 17.0.6 2023-01-17OpenJDK 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)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)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"}}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" } }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.orgBUILD 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 1FAILURE: 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 1FAILURE: 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了。
总结
- 安卓项目的启动是通过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,);_processUtils.stream( command, workingDirectory: project.android.hostAppGradleRoot.path, allowReentrantFlutter: true, environment: <String, String>{ if (javaHome != null) AndroidSdk.javaHomeEnvironmentVariable: javaHome, }, mapFunction: consumeLog, );_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