最近在配置flutter开发环境的时候,出现了很多问题。
我是下载的 flutter源码 ,切换到了stable
分支,当前版本号为 1.22.6
。Android Studio
版本为最新的稳定版 4.1.2
。
问题1
明明安装了android studio,但是 flutter doctor
一直显示 Android Studio
没有安装
[!] Android Studio (not installed)
使用如下命令设置一下即可解决
flutter config --android-studio-dir=$your-android-studio-directory
通过后文的分析,发现flutter
在linux
环境下默认搜索如下路径
- ~/AndroidStudio{major.minor}/system/.home (major.minor表示版本号,例如4.1, 3.3等)
- /opt/android-studio
- ~/android-studio
如果不是这几个默认安装路径,那就需要手动设置 android-studio-dir
问题2
明明安装了 flutter和dart
插件,但是 flutter doctor
命令一直提示检测不到这两个插件,google搜了一下,没有任何能解决这个问题的方案,好在有源码,那我们就能自己解决了。
[!] Android Studio
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
以前从来没看过flutter的代码,我们如何开始呢?先看错误提示,于是我们可以根据错误提示的字符串来进行搜索,根据编程经验插件名称肯定是动态写入的,于是我们试试搜索 plugin not installed
@debian-ts:~/tools/flutter$ rg 'plugin not installed'
packages/flutter_tools/lib/src/intellij/intellij.dart
44: '$title plugin not installed; this adds $title specific functionality.'));
packages/flutter_tools/test/general.shard/intellij/intellij_test.dart
88: expect(message.message, contains('Dart plugin not installed'));
92: expect(message.message, contains('Flutter plugin not installed'));
搜到了两个文件,很明显逻辑应该是在 packages/flutter_tools/lib/src/intellij/intellij.dart
这个文件中,我们打开看一下,发现 validatePackage
函数是用来做插件检测的
void validatePackage(
List<ValidationMessage> messages,
List<String> packageNames,
String title, {
Version minVersion,
})
搜一下谁调用了这个函数
@debian-ts:~/tools/flutter$ rg validatePackage
packages/flutter_tools/lib/src/doctor.dart
749: plugins.validatePackage(messages, <String>['flutter-intellij', 'flutter-intellij.jar'],
751: plugins.validatePackage(messages, <String>['Dart'], 'Dart');
packages/flutter_tools/lib/src/android/android_studio_validator.dart
45: plugins.validatePackage(
51: plugins.validatePackage(messages, <String>['Dart'], 'Dart');
packages/flutter_tools/test/general.shard/intellij/intellij_test.dart
59: plugins.validatePackage(messages, <String>['Dart'], 'Dart');
60: plugins.validatePackage(messages,
81: plugins.validatePackage(messages, <String>['Dart'], 'Dart');
82: plugins.validatePackage(messages,
packages/flutter_tools/lib/src/intellij/intellij.dart
19: void validatePackage(
很明显 packages/flutter_tools/lib/src/android/android_studio_validator.dart
这个文件中有相应的逻辑,打开文件一看发现逻辑非常清晰
final IntelliJPlugins plugins = IntelliJPlugins(_studio.pluginsPath);
plugins.validatePackage(
messages,
<String>['flutter-intellij', 'flutter-intellij.jar'],
'Flutter',
minVersion: IntelliJPlugins.kMinFlutterPluginVersion,
);
plugins.validatePackage(messages, <String>['Dart'], 'Dart');
插件的目录是 _studio.pluginsPath
,我们先来调试一下,在上述部分代码前加入一行调试代码
print("****** ${_studio.pluginsPath}");
现在我们要重新编译flutter tool,然后看看这个 _studio.pluginsPath
到底是什么值,如何重新编译呢?只要删除 $flutter_sdk/bin/cache/flutter_tools.stamp
文件,再执行 flutter doctor
命令就能自动触发重新编译了。
@debian-ts:~/tools/flutter$ rm bin/cache/flutter_tools.stamp
@debian-ts:~/tools/flutter$ flutter doctor
Building flutter tool...
Doctor summary (to see all details, run flutter doctor -v):
******~/.AndroidStudio0.0/config/plugins
[✓] Flutter (Channel stable, 1.22.6, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[!] Android Studio
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
看到结果真是大吃一惊,竟然是 ~/.AndroidStudio0.0/config/plugins
,什么鬼!
既然知道了路径,那么第一种解决办法就产生了,在我使用的 debian buster
系统上,Android Studio 4.1.2
的插件安装目录为 ~/.local/share/Google/AndroidStudio4.1
,我们创建一个指向这个地方的软链接即可。
解决方案1
@debian-ts:~/tools/flutter$ mkdir -p ~/.AndroidStudio0.0/config
@debian-ts:~/tools/flutter$ ln -s ~/.local/share/Google/AndroidStudio4.1 ~/.AndroidStudio0.0/config/plugins
创建软链接之后,执行 flutter doctor
,果然没问题了。
很明显我们不能止步于此,这个方案是能解决问题,但是有点太奇怪了。那么我们继续分析,看样子是 flutter
没有识别到 android studio
,跟第一个问题很像,第一个问题中我们必须用参数 --android-studio-dir
手动指定 android studio
的目录。 即使我们手动指定了安装目录,flutter
知道android studio
安装了,但是识别出来的版本号仍然是0.0
,那是为什么呢?
还是老样子,从 --android-stdio-dir
选项来入手分析,我们搜索 android-studio-dir
,查看读取的这个选项在哪个地方用到了,具体过程就不详述了。我们发现检测 android studio
的逻辑在 packages/flutter_tools/lib/src/android/android_studio.dart
文件中,
static List<AndroidStudio> allInstalled() =>
globals.platform.isMacOS ? _allMacOS() : _allLinuxOrWindows();
检测插件的逻辑在 packages/flutter_tools/lib/src/intellij/intellij.dart
文件的 _hasPackage
方法中
bool _hasPackage(String packageName) {
final String packagePath = globals.fs.path.join(pluginsPath, packageName);
if (packageName.endsWith('.jar')) {
return globals.fs.isFileSync(packagePath);
}
return globals.fs.isDirectorySync(packagePath);
}
pluginsPath
的获取在 packages/flutter_tools/lib/src/android/android_studio.dart
中,最终发现,总之这个插件路径的判断逻辑漏洞很多。再查看一下 master
上的最新代码,看看官方是否有改进,发现没什么改进,但是官方改变了 flutter doctor
的输出,在 master
的版本上,根本就不会提示插件未安装的警告。所以我们得到第二个解决办法
解决方案2
直接忽略 flutter doctor
的未安装flutter
和dart
插件的警告,没什么用,只要你的 Android Studio
确实安装了能正常开发即可。
问题3
正常创建了flutter application
,在命令行执行 flutter run
没有任何问题, Android Studio
能看到手机设备已经连接,但是选择不了。
这个问题就没有办法解决了,很愁人,有知道的大佬望不吝赐教。照理说都是稳定版,不应该这么多坑呀。