將 Flutter module 整合到 Android 專案

Flutter 可以作為 Gradle 子專案原始碼或者 AAR 嵌入到現有的 Android 應用程式中。

開發者可以使用帶有 Flutter 外掛 的 Android Studio 或手動完成整個整合流程。

使用 Android Studio

直接使用 Android Studio 是在現有應用中自動整合 Flutter 模組比較便捷的方法。在 Android Studio 中,你可以在一個專案中同時編寫 Android 程式碼和 Flutter 程式碼,還可以繼續使用各種常用的 IntelliJ Flutter 外掛功能,例如 Dart 程式碼自動自動完成、熱重載和 widget 檢查器等。

只有在 Android Studio 3.6 及以上的版本,配合 42 以上版本的 IntelliJ Flutter 外掛 才能直接透過 Android Studio 執行整合流程,並且,Android Studio 目前僅支援以 Gradle 子專案原始碼的方式整合,而不能以 AAR 方式整合。有關這兩種方式的區別及更多詳細資訊,請參見下文。

在 Android Studio 開啟現有的 Android 專案並點選選單按鈕 File > New > New Module… ,這樣就可以創建出一個可以整合的新 Flutter 模組,或者選擇匯入已有的 Flutter 模組。

如果你想建立一個新的 Flutter 模組,則可以直接在嚮導視窗中填寫模組名稱、路徑等資訊。

此時,Android Studio 外掛就會自動為這個 Android 專案配置新增 Flutter 模組作為依賴項,這時整合應用就已準備好進行下一步的建構。

現在,應用程式已經包含了 Flutter 模組作為依賴項,你可以跳轉至 向 Android 應用中新增 Flutter 頁面 執行後續步驟。

手動整合

如果想要在不使用 Flutter 的 Android Studio 外掛的情況下手動將 Flutter 模組與現有的 Android 應用整合,可以參考以下步驟:

建立 Flutter 模組

假設你在 some/path/MyApp 路徑下已有一個 Android 應用,並且你希望 Flutter 專案作為同級專案:

$ cd some/path/
$ flutter create -t module --org com.example my_flutter

這會建立一個 some/path/my_flutter/ 的 Flutter 模組專案,其中包含一些 Dart 程式碼來幫助你入門以及一個隱藏的子資料夾 .android/.android 資料夾包含一個 Android 專案,該專案不僅可以幫助你透過 flutter run 執行這個 Flutter 模組的獨立應用,而且還可以作為封裝程式來幫助引導 Flutter 模組作為可嵌入的 Android 庫。

引入 Java 8

Flutter Android 引擎需要使用到 Java 8 中的新特性。

在嘗試將 Flutter 模組專案整合到宿主 Android 應用之前,請先確保宿主 Android 應用的 build.gradle 檔案的 android { } 塊中聲明瞭以下源相容性,例如:

android {
  //...
  compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
  }
}

將 Flutter module 作為依賴項

接下來,將 Flutter 模組新增為 Gradle 中宿主應用程式的依賴項。主要有兩種方法實現。 AAR 機制可以為每個 Flutter 模組建立 Android AAR 作為依賴媒介。當你的宿主應用程式開發者不想安裝 Flutter SDK 時,這是一個很好方案,但是,如果你想要經常編譯,那麼每次都需要重新編譯一次,該步驟不可避免。

直接將 Flutter 模組的原始碼作為子專案的依賴機制是一種便捷的一鍵式建構方案,但此時需要另外安裝 Flutter SDK,這是目前 Android Studio IDE 外掛使用的機制。

方案 A - 依賴 Android Archive (AAR)

這種方式會將 Flutter 庫打包成由 AAR 和 POM artifacts 組成的本地 Maven 儲存庫。這種方案可以使你的團隊不需要安裝 Flutter SDK 即可編譯宿主應用。之後,你可以從本地或遠端儲存庫中分發更新 artifacts。

假設你在 some/path/my_flutter 下建構 Flutter 模組,執行如下命令:

$ cd some/path/my_flutter
$ flutter build aar

然後,根據螢幕上的提示完成整合操作。

詳細地說,該命令應用於建立(預設情況下建立 debug/profile/release 所有模式)本地儲存庫,主要包含以下檔案:

build/host/outputs/repo
└── com
    └── example
        └── my_flutter
            ├── flutter_release
            │   ├── 1.0
            │   │   ├── flutter_release-1.0.aar
            │   │   ├── flutter_release-1.0.aar.md5
            │   │   ├── flutter_release-1.0.aar.sha1
            │   │   ├── flutter_release-1.0.pom
            │   │   ├── flutter_release-1.0.pom.md5
            │   │   └── flutter_release-1.0.pom.sha1
            │   ├── maven-metadata.xml
            │   ├── maven-metadata.xml.md5
            │   └── maven-metadata.xml.sha1
            ├── flutter_profile
            │   ├── ...
            └── flutter_debug
                └── ...

要依賴 AAR,宿主應用必須能夠找到這些檔案。

為此,需要在宿主應用程式中修改 app/build.gradle 檔案,使其包含本地儲存庫和上述依賴項:

android {
  // ...
}

repositories {
  maven {
    url 'some/path/my_flutter/build/host/outputs/repo'
    // This is relative to the location of the build.gradle file
    // if using a relative path.
  }
  maven {
    url 'https://storage.googleapis.com/download.flutter.io'
  }
}

dependencies {
  // ...
  debugImplementation 'com.example.flutter_module:flutter_debug:1.0'
  profileImplementation 'com.example.flutter_module:flutter_profile:1.0'
  releaseImplementation 'com.example.flutter_module:flutter_release:1.0'
}

你的應用程式現在添加了 Flutter 模組作為依賴項,下面,你可以按照 向 Android 應用中新增 Flutter 頁面 中的後續步驟繼續操作。

方案 B - 依賴模組的原始碼

該方式可以使你的 Android 專案和 Flutter 專案能夠同步一鍵式建構。當你需要同時在這兩個專案中進行快速迭代時,這種方案非常方便,但是此時,你的團隊必須安裝 Flutter SDK 才能建構宿主應用程式。

將 Flutter 模組作為子專案新增到宿主應用的 settings.gradle 中:

// Include the host app project.
include ':app'                                    // assumed existing content
setBinding(new Binding([gradle: this]))                                // new
evaluate(new File(                                                     // new
  settingsDir.parentFile,                                              // new
  'my_flutter/.android/include_flutter.groovy'                         // new
))                                                                     // new

假設 my_flutterMyApp 是同級目錄。

binding 和 evaluation 指令碼可以使 Flutter 模組將其自身(如 :flutter)和該模組使用的所有 Flutter 外掛(如 :package_info:video_player 等)都包含在 settings.gradle 的評估的上下文中。

在你的應用中引入對 Flutter 模組的依賴:

dependencies {
  implementation project(':flutter')
}

此時,你的應用程式已將 Flutter 模組新增為依賴項,下面,你可以按照 向 Android 應用中新增 Flutter 頁面 中的後續步驟繼續操作。