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 能看到手機設備已經連接,但是選擇不了。

這個問題就沒有辦法解決了,很愁人,有知道的大佬望不吝賜教。照理說都是穩定版,不應該這麼多坑呀。

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