Flutter问题记录 - Unable to find bundled Java version(续)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
文章目录
前言
在Flutter问题记录 - Unable to find bundled Java version文章中主要对Unable to find bundled Java version
报错进行了分析虽然从最终结果上看Android端构建运行失败和出现这个报错的原因应该是一致的但是没有进行原因分析。这里做一些简单分析作为上篇文章的补充。
开发环境
- Android Studio: 2022.1.1
- Flutter: 3.3.10
问题描述
Android端构建运行失败报错信息如下
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
问题分析
当我们在Android Studio中点击运行Flutter项目到Android设备时控制台会输出
Launching xxx.dart on xxx in debug mode...
Running Gradle task 'assembleDebug'...
...
当然如果项目没执行过pub get
还会有这个输出
Running "flutter pub get" in xxx...
对于Launching xxx.dart on xxx in debug mode...
输出和要分析的问题没有什么关系不过如果你对整个运行流程感兴趣的话可以在Flutter框架项目下的packages/flutter_tools/lib/src/resident_runner.dart
文件中找到这个输出的相关代码
final String modeName = coldRunner.debuggingOptions.buildInfo.friendlyModeName;
final bool prebuiltMode = coldRunner.applicationBinary != null;
globals.printStatus(
'Launching ${getDisplayPath(coldRunner.mainPath, globals.fs)} '
'on ${device!.name} in $modeName mode...',
);
对于Running Gradle task 'assembleDebug'...
输出就是这次问题分析的关键了在Flutter框架项目下搜索关键词Running Gradle task
从上篇文章的问题分析可以知道问题出在Android Studio移除了jre
目录进而导致javaPath
的拼接出现了问题。那现在这问题会不会是因为运行Gradle task
时也用到了错误的javaPath
呢继续在gradle.dart
文件中搜索javaPath
。
gradle.dart
文件中buildGradleApp
方法的部分代码
try {
exitCode = await _processUtils.stream(
command,
workingDirectory: project.android.hostAppGradleRoot.path,
allowReentrantFlutter: true,
environment: <String, String>{
if (javaPath != null)
'JAVA_HOME': javaPath!,
},
mapFunction: consumeLog,
);
} on ProcessException catch (exception) {
consumeLog(exception.toString());
// Rethrow the exception if the error isn't handled by any of the
// `localGradleErrors`.
if (detectedGradleError == null) {
rethrow;
}
} finally {
status.stop();
}
可以看到确实用到了javaPath
那这个和android_studio.dart
文件里面的javaPath
有什么关联吗选中javaPath
跳转定义的地方发现来到了android_studio.dart
文件是一个顶级方法
String? get javaPath => globals.androidStudio?.javaPath;
Dart的顶级方法意味着只要导入android_studio.dart
文件就可以直接调用javaPath
方法。从方法定义中的javaPath
继续跳转来到了AndroidStudio
类里面。
AndroidStudio
类部分代码
class AndroidStudio implements Comparable<AndroidStudio> {
AndroidStudio(
this.directory, {
Version? version,
this.configured,
this.studioAppName = 'AndroidStudio',
this.presetPluginsPath,
}) : version = version ?? Version.unknown {
_init(version: version);
}
String? _javaPath;
bool _isValid = false;
final List<String> _validationMessages = <String>[];
String? get javaPath => _javaPath;
void _init({Version? version}) {
_isValid = false;
_validationMessages.clear();
if (configured != null) {
_validationMessages.add('android-studio-dir = $configured');
}
if (!globals.fs.isDirectorySync(directory)) {
_validationMessages.add('Android Studio not found at $directory');
return;
}
final String javaPath = globals.platform.isMacOS ?
version != null && version.major < 2020 ?
globals.fs.path.join(directory, 'jre', 'jdk', 'Contents', 'Home') :
globals.fs.path.join(directory, 'jre', 'Contents', 'Home') :
globals.fs.path.join(directory, 'jre');
final String javaExecutable = globals.fs.path.join(javaPath, 'bin', 'java');
if (!globals.processManager.canRun(javaExecutable)) {
_validationMessages.add('Unable to find bundled Java version.');
} else {
RunResult? result;
try {
result = globals.processUtils.runSync(<String>[javaExecutable, '-version']);
} on ProcessException catch (e) {
_validationMessages.add('Failed to run Java: $e');
}
if (result != null && result.exitCode == 0) {
final List<String> versionLines = result.stderr.split('\n');
final String javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0];
_validationMessages.add('Java version $javaVersion');
_javaPath = javaPath;
_isValid = true;
} else {
_validationMessages.add('Unable to determine bundled Java version.');
}
}
}
}
继续在类里面搜索_javaPath
来到了AndroidStudio
类的初始化方法_init
可以发现Android端构建运行和flutter doctor
命令执行一样也用到了AndroidStudio
类里面拼接的javaPath
。当Android Studio移除jre
目录后初始化androidStudio
对象时拼接的javaPath
路径有问题导致没有给_javaPath
赋值从而导致Android端构建运行时获取的javaPath
是null
。由此可以验证Android端构建运行失败的原因和出现Unable to find bundled Java version
报错的原因是一致的。
解决方案
请看这篇文章Flutter问题记录 - Unable to find bundled Java version中的解决方案。
最后
如果这篇文章对你有所帮助请不要吝啬你的点赞👍加星🌟谢谢~