AndroidStudio安装了flutter插件,但是flutter doctor识别不到的问题解决

最近在配置flutter开发环境的时候,出现了很多问题。

我是下载的 flutter源码 ,切换到了stable 分支,当前版本号为 1.22.6Android Studio 版本为最新的稳定版 4.1.2

问题1

明明安装了android studio,但是 flutter doctor 一直显示 Android Studio 没有安装

[!] Android Studio (not installed)

使用如下命令设置一下即可解决

flutter config --android-studio-dir=$your-android-studio-directory

通过后文的分析,发现flutterlinux环境下默认搜索如下路径

  • ~/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 的未安装flutterdart插件的警告,没什么用,只要你的 Android Studio确实安装了能正常开发即可。

问题3

正常创建了flutter application,在命令行执行 flutter run 没有任何问题, Android Studio 能看到手机设备已经连接,但是选择不了。

这个问题就没有办法解决了,很愁人,有知道的大佬望不吝赐教。照理说都是稳定版,不应该这么多坑呀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章