Flutter integrates into existing Android native projects – in an integrated manner

Flutter can be embedded into an existing Android native project as a Gradle subproject or AAR file. The integration process can be done using Android Studio plug-ins or manual integration. Starting with Flutter V1.26, Flutter supports the integration of multiple Flutter engines, screens, View instance.

Note: Your native Android project may support MIPS or x86 architecture. Flutter currently (as of September 2021) only supports AOT mode compilation of X86_64, armabI-v7A, and arm64-V8A. You can use the abiFilters Android Gradle plugin API on your app to limit supported architectures. Avoid runtime exceptions caused by the lack of libflutter. So, such as android {//... defaultConfig { ndk { // Filter for architectures supported by Flutter. abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'}}} Flutter references are available in x86 and x86 -- 64 versions, and the Flutter module behaves correctly when debugged in simulator JIT mode.Copy the code

Integrate with Android Studio

Android Studio automatically integrates with the Flutter Module is very convenient. You can edit both Android native code and Flutter code in your project, and can continue to use Flutter plug-ins, such as Dart code auto-completion, Hot Reload, Widget checking, etc.

The process added to the app supports the Android Studio 3.6, 42+ IntelliJ Plugin for Flutter. Android Studio integration only supports integration using the source Gradle subproject, not the AAR.

Use the Android Studio menu bar File>New>New Module… You can create a new Flutter Module integration, or select a previously created Flutter Module

The Android Studio plugin automatically configures the Android project by adding the Flutter Module as a dependency.


Manual integration

To manually integrate the Flutter Module into your Android project without using the Android Studio plugin, do as follows:

Create a Module

Suppose we have an Android app in some/path/MyApp path and we want our Flutter project to be in the peer directory

cd some/path/
flutter create -t module --org com.adamin flutter_m3
Copy the code

This creates a Flutter Module in some/path/flutter_m3, which contains some Dart code as your initial code and a hidden folder called **. Android. Android contains an Android project. It helps you run the Flutter module independently with the Flutter run** command. It is also a wrapper that helps boot the Flutter module into an embeddable Android library.

Java 8 demand

The Flutter Android engine uses Java 8 features. Before attempting to connect the Flutter Module to the host Android app, make sure that the ** Android {}* module under the build.gradle file of the host Android app declares source compatibility as follows:

android { //... CompileOptions {sourceCompatibility 1.8 targetCompatibility 1.8}}Copy the code

Add a Flutter Module as a dependency

Now we can add a Flutter Module to Gradle as the host app’s dependencies. There are two ways to do this. The AAR mechanism packages your Flutter Module by creating a common Android AAR as a medium, which is great if your downstream application builders don’t want to install the Flutter SDK. But if you build often, it adds a build step.

The source subproject mechanism is a nice one-click build, but relies on the Flutter SDK, which is used by the Android Studio plugin.

Approach 1 – Rely on Android Archive (AAR)

This way you Flutter

Dependencies are packaged into a common local Maven repository consisting of AAR and POM artifacts. This enables your team to build host apps without installing the Flutter SDK. You can distribute artifacts from local or native repositories.

The build command is as follows:

cd /some/path/flutter_m3
flutter build aar
Copy the code

Then follow the output instructions on the terminal integration.

This step may cause an error, with the following error message:

Exception in thread "main" java.util.zip.ZipException: zip END header not found
        at java.base/java.util.zip.ZipFile$Source.zerror(ZipFile.java:1581)
        at java.base/java.util.zip.ZipFile$Source.findEND(ZipFile.java:1476)
        at java.base/java.util.zip.ZipFile$Source.initCEN(ZipFile.java:1483)
        at java.base/java.util.zip.ZipFile$Source.<init>(ZipFile.java:1288)
        at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1251)
        at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:732)
        at java.base/java.util.zip.ZipFile$CleanableResource.get(ZipFile.java:849)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:247)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:177)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:191)
        at org.gradle.wrapper.Install.unzip(Install.java:214)
        at org.gradle.wrapper.Install.access$600(Install.java:27)
        at org.gradle.wrapper.Install$1.call(Install.java:74)
        at org.gradle.wrapper.Install$1.call(Install.java:48)
        at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:65)
        at org.gradle.wrapper.Install.createDist(Install.java:48)
        at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:128)
        at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)


Gradle task assembleAarDebug failed with exit code 1.
Copy the code

C:\Users\ user name \. Gradle \wrapper\dists\gradle-6.7-all When gradlew. Bat is executed, gradle is automatically downloaded and the build is decompressed. The last two lines of the terminal output the following information to indicate a successful build.


BUILD SUCCESSFUL in 1m 25s
1 actionable task: 1 executed
Copy the code

Then we continue to execute the flutter build aar directive and the terminal will output the following information:

D:\android\nettyAndroidDemo\flutter_m3\.android>flutter build aar Changing current working directory to: D:\android\nettyAndroidDemo\flutter_m3 Building without sound null safety For more information see https://dart.dev/null-safety/unsound-null-safety Running Gradle task 'assembleAarDebug'... Running Gradle task 'assembleAarDebug'... Done 343s √ Built build\host\outputs\repo. Running Gradle task 'assembleAarProfile' Done 343s √ Built build\host\outputs\repo. Running Gradle task 'assembleAarProfile'... Done 38.3s √ Built build\host\outputs\repo. Running Gradle task 'assembleAarRelease'... Running Gradle task 'assembleAarRelease'... Done 32.5s √ Built build, host, outputs, repo. Consuming the Module 1. Open <host> app, build.gradle 2. Ensure you have the repositories configured, otherwise add them: String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ? : "https://storage.googleapis.com" repositories { maven { url 'D:\android\nettyAndroidDemo\flutter_m3\build\host\outputs\repo' } maven { url "$storageUrl/download.flutter.io" } } 3. Make the host app depend on the Flutter module: Dependencies {debugImplementation 'com.adamin. Flutter_m3 :flutter_debug:1.0' profileImplementation 'com.adamin.flutter_m3:flutter_profile:1.0' releaseImplementation 'com.adamin.flutter_m3:flutter_release:1.0'} 4.add the `profile` build type: android { buildTypes { profile { initWith debug } } } To learn more, visit https://flutter.dev/go/build-aarCopy the code

To use aar, configure Gradle in the following four steps:

  1. Open the build.gradle of the host app

  2. Configuring a Local Warehouse

    String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ? : "https://storage.googleapis.com" repositories { maven { url 'D:\android\nettyAndroidDemo\flutter_m3\build\host\outputs\repo' } maven { url "$storageUrl/download.flutter.io" } }Copy the code
    1. Add the dependent

      Dependencies {debugImplementation 'com.adamin. Flutter_m3 :flutter_debug:1.0' profileImplementation 'com. Adamin. Flutter_m3: flutter_profile: 1.0' releaseImplementation 'com. Adamin. Flutter_m3: flutter_release: 1.0'}Copy the code
    2. Add a Profile build type

       android {
            buildTypes {
              profile {
                initWith debug
              }
            }
          }
      Copy the code
    Method 2, rely on the source code of the FLUTTER module

    Include the flutter Module in the host Android app’s settings.gradle file:

    // Include the host app project. include ':app' // assumed existing content setBinding(new Binding([gradle: This]) // evaluate(new File(// new settingsdir.parentfile, // here if the flutter module is in the root of the host app directory, ParentFile // new 'my_flutter/.android/include_flutter. Groovy '// new)) // newCopy the code

    Here binding and evaluate allow the Flutter module to include itself in the context clock evaluated by settings.gradle

(: Flutter) and the plugin that the Flutter module depends on.

Add a flutter module dependency to the host app’s build.gradle:

dependencies {
  implementation project(':flutter')
}

Copy the code

This allows you to manually integrate Flutter into your Android native project.

conclusion

The Android native project integrates Flutter in two ways:

  1. The Android Studio menu integrates File>New>Module to create or select Flutter Module. Android Studio automatically configures and depends on modules
  2. Manual integration
    • performflutter create -t module --org com.adamin module_nameCreate a module
    • There are two types of dependency integration, AAR or source dependency.