將 Flutter module 整合到 Android 專案

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

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

整合 Flutter 模組

使用 Android Studio 整合

直接使用 Android Studio 是在現有應用中自動整合 Flutter 模組比較便捷的方法。在 Android Studio 中,你可以在一個專案中同時編寫 Android 程式碼和 Flutter 程式碼。

你還可以繼續使用各種常用的 IntelliJ Flutter 外掛功能,例如 Dart 程式碼自動補全、熱過載和 widget 檢查器等。

在 Android Studio 2022.2 及以上的版本,配合 IntelliJ Flutter 外掛 就可以直接透過 Android Studio 執行整合流程。 Android Studio 需要將你的 Flutter 模組作為依賴。

  1. 在 Android Studio 中開啟你的 Android 專案。

  2. 前往 File > New > New Project…,此時 New Project 彈窗會顯示。

  3. 選擇 Flutter

  4. 填寫你的 Flutter SDK path 並點選 Next 繼續。

  5. 完成你的 Flutter 模組設定。

    • 如果你的專案是已有的:

      1. 點選 Project location 右側的 選擇現有的專案。

      2. 前往你的 Flutter 專案的目錄所在位置。

      3. 點選 開啟

    • 如果你需要建立一個新的 Flutter 專案:

      1. 完成設定彈窗的內容。

      2. Project type 選單中,選擇 Module

  6. 點選完成。

不使用 Android Studio 進行整合

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

建立 Flutter 模組

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

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

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

Java 版本要求

Flutter 需要使用 Java 11 的屬性。

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

MyApp/app/build.gradle
android {
  //...
  compileOptions {
    sourceCompatibility 11 // The minimum value
    targetCompatibility 11 // The minimum value
  }
}

Centralize repository settings

Starting with Gradle 7, Android recommends using centralized repository declarations in settings.gradle instead of project or module level declarations in build.gradle files.

Before attempting to connect your Flutter module project to your host Android app, make the following changes.

  1. Remove the repositories block in all of your app’s build.gradle files.

    // Remove the following block, starting on the next line
        repositories {
            google()
            mavenCentral()
        }
    // ...to the previous line
    
  2. Add the dependencyResolutionManagement displayed in this step to the settings.gradle file.

    dependencyResolutionManagement {
      repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
      repositories {
        google()
        mavenCentral()
      }
    }
    

將 Flutter module 作為依賴項

主要有兩種方法將 Flutter 模組新增為 Gradle 中宿主應用程式的依賴項。

  1. AAR 整合 AAR 機制可以為每個 Flutter 模組建立 Android AAR 作為依賴媒介。當你的宿主應用程式開發者不想安裝 Flutter SDK 時,這是一個很好方案。但是每次修改都需要重新編譯。

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

依賴 Android Archive (AAR)

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

假設你在 some/path/flutter_module 下建立 Flutter 模組,執行如下指令:

cd some/path/flutter_module
flutter build aar

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

詳細地說,該指令應用於建立(debug/profile/release 所有模式) 本地倉庫,主要包含以下檔案:

build/host/outputs/repo
└── com
    └── example
        └── flutter_module
            ├── 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,宿主應用必須能夠找到這些檔案。

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

dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
  repositories {
    google()
    mavenCentral()

  // Add the new repositories starting on the next line...
    maven {
      url 'some/path/flutter_module/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'
    }
  // ...to before this line  
  }
}

</br>

基於 Kotlin DSL 的 Android 專案

在基於 Kotlin DSL Android 專案的 aar 建立完成後,請按照以下步驟新增 flutter_module。

在 Android 專案的 app/build.gradle 檔案中將 flutter module 列為依賴項。

MyApp/app/build.gradle.kts
android {
    buildTypes {
        release {
          ...
        }
        debug {
          ...
        }
        create("profile") {
            initWith(getByName("debug"))
        }
}
dependencies {
  // ...
  debugImplementation "com.example.flutter_module:flutter_debug:1.0"
  releaseImplementation 'com.example.flutter_module:flutter_release:1.0'
  add("profileImplementation", "com.example.flutter_module:flutter_profile:1.0")
}

profileImplementation ID 是在宿主專案的 app/build.gradle 檔案中實施的自定義 configuration

host-project/app/build.gradle.kts
configurations {
    getByName("profileImplementation") {
    }
}
MyApp/settings.gradle.kts
include(":app")

dependencyResolutionManagement {
    repositories {
        maven(url = "https://storage.googleapis.com/download.flutter.io")
        maven(url = "some/path/flutter_module_project/build/host/outputs/repo")
    }
}

依賴模組的原始碼

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

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

MyApp/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
    'flutter_module/.android/include_flutter.groovy'                   // new
))                                                                     // new

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

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

MyApp/app/build.gradle
dependencies {
    implementation project(':flutter')
}

此時,你的應用程式已將 Flutter 模組新增為依賴項,

接下來你可以按照 向 Android 應用中新增 Flutter 頁面 繼續進一步的整合。