Android native project integration Flutter solution

  • 2021-12-12 05:48:48
  • OfStack

Learn how to integrate Flutter in an Android native project under 1

Build configuration


 Execute commands at the root of the native project 
 
flutter create -t module --org {package_name} {module_name}
 
//  Here  module_name  The command of follows  Android  Sub  module  The name of. There can be no midline. 
 
//  For example , 
 
flutter create -t module --org com.engineer.mini.flutter flutter_sub
 
//  Here  module_name  The command of follows  Android  Sub  module  The name of. There can be no midline. 
 
//  For example , 
 
flutter create -t module --org com.engineer.mini.flutter flutter_sub
</pre>

Results

Creating project sub_flutter...
sub_flutter/test/widget_test.dart (created)
sub_flutter/sub_flutter.iml (created)
sub_flutter/.gitignore (created)
sub_flutter/.metadata (created)
sub_flutter/pubspec.yaml (created)
sub_flutter/README.md (created)
sub_flutter/lib/main.dart (created)
sub_flutter/sub_flutter_android.iml (created)
sub_flutter/.idea/libraries/Dart_SDK.xml (created)
sub_flutter/.idea/modules.xml (created)
sub_flutter/.idea/workspace.xml (created)
Running "flutter pub get" in sub_flutter... 1,054ms
Wrote 11 files.

Finally, the above file is generated. Notice that the command of flutter pub get is automatically executed at the end. For what flutter pub get has done, please refer to the following.

Here, the submodule is created in the root directory of the project only to put the code in a warehouse, which is convenient for maintenance and can be placed anywhere on the hard disk in theory.

Configure native project settings. gradle

Before configuring settings. gradle, let's briefly review the basics of Gradle.

If you know the configuration related to Gradle, 1 will definitely see a concept, that is, convention is better than configuration. What does it mean? According to the object-oriented idea, every project is a huge Project class, and there are many attributes in the whole class. Every project we create is actually a concrete Project object (that is, an instance). Convention is better than configuration, which means that when project is instantiated, its internal properties already have default values. So how do we know which default values are? Execute in the project root directory


./gradlew properties

You can get 1 default configuration of the whole Project, such as (some results are excerpted here)


------------------------------------------------------------
Root project
------------------------------------------------------------
 
allprojects: [root project 'MiniApp', project ':app', project ':thirdlib']
android.agp.version.check.performed: true
android.enableJetifier: true
android.enableR8: true
android.enableR8.libraries: true
android.useAndroidX: true
buildDir: /Users/username/Documents/mygithub/MinApp/build
buildFile: /Users/username/Documents/mygithub/MinApp/build.gradle
projectDir: /Users/username/Documents/mygithub/MinApp
rootDir: /Users/username/Documents/mygithub/MinApp
rootProject: root project 'MiniApp'

There are currently one that we have configured, such as useAndroidX, but one that is agreed upon, such as the buildDir folder of the project root for the entire project.

Execute


./gradlew :app:properties

Excerpt some results


buildDir: /Users/username/Documents/mygithub/MinApp/app/build
buildFile: /Users/username/Documents/mygithub/MinApp/app/build.gradle

You will get some configuration information about app and module at this stage. Of course, these configuration information are not only agreed, but also your own configuration, such as buildToolsVersion, signature and other related information. It can be seen that buildDir is different from the whole project.

Back to the topic, see how to integrate the sub_flutter module we just created into the project. (Strictly speaking, it is not an integration of sub_flutter module, because it is only an flutter module, and in the main project of Android, only sub-Android module can be integrated, so what to do, let's take a look at the mystery below)

According to the official operation method, we will be asked to add the following configuration to 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

First look at the value of settingsDir here. Add directly in settings. gradle


println "settings.dir=" + settingsDir
println "settings.dir.parent=" + settingsDir.parent

You will see the output after sync


settings.dir=/Users/username/Documents/mygithub/MinApp
settings.dir.parent=/Users/username/Documents/mygithub

Therefore, the above configuration information, that is to say, combines the parent directory of the directory where settings is located with the directory we configured, finds a file named include_flutter. groovy, and then executes it.

As mentioned earlier, when creating a child module, it can be in the root directory of the project or in other locations. If it is in other locations, my_flutter here can be replaced by your absolute strength in creating the directory.

This is created directly in the root directory, so the above configuration can be simplified to


setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir, 'sub_flutter/.android/include_flutter.groovy'))
include ':sub_flutter'
####  About  include_flutter.groovy

As mentioned above, the configuration of settings. gradle is actually to execute the file include_flutter. groovy. You can simply look at this file


def scriptFile = getClass().protectionDomain.codeSource.location.toURI()
def flutterProjectRoot = new File(scriptFile).parentFile.parentFile
 
gradle.include ":flutter"
gradle.project(":flutter").projectDir = new File(flutterProjectRoot, ".android/Flutter")
 
def localPropertiesFile = new File(flutterProjectRoot, ".android/local.properties")
def properties = new Properties()
 
assert localPropertiesFile.exists(), ":exclamation:️The Flutter module doesn't have a `$localPropertiesFile` file." +
                                     "\nYou must run `flutter pub get` in `$flutterProjectRoot`."
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
 
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
gradle.apply from: "$flutterSdkPath/packages/flutter_tools/gradle/module_plugin_loader.gradle"

. android is actually an Android project, which contains an Flutter folder, and this Flutter is an Android module of library type, which can be seen from his build. gradle file. What include_flutter. groovy does is to name the current library as an moudle of flutter. Then check the relevant configuration of sdk in local. properties in the project, and finally execute gradle script in FlutterSDK, so the specific analysis will not be expanded here.

That is, there is now an Android Library Module named flutter. This module contains all the configurations of flutter. If we rely on this module, we are relying on Flutter.

Dependence on flutter

Finally, add in the dependencies closure of build. gradle of the native project application-module


./gradlew properties
0

At this point, the native project has a dependency on Flutter, and can use View of Flutter.

At this point, the current native project contains all the dependencies of Flutter SDK, and the related contents of UI should be written in dart or main. dart, and then we can add the rendered contents of dart to the existing projects in the form of Activity, Fragment or View.

flutter pub get

flutter pub get or pub get is a command that is often used when using the third party lib or version update when doing flutter. This command will pull related dependencies. In fact, this command will automatically generate native items of Android and iOS. For example, in the sub_flutter module we created, native project directories for. android and. ios are automatically generated. At the same time, these two directories are dot-headed, Then, in general, it is a hidden file. At the same time, it can be seen from the. gitignore file that these two folders are ignored in the form of flutter module. After all, the core of flutter module is to facilitate integration into native projects in the form of module. The two native directories inside are for the convenience of integration on one hand, and for the convenience of directly running and executing hot-reload debugging on the other hand.

The above is the Android native project integration Flutter solution details, more information about Android integration Flutter please pay attention to other related articles on this site!


Related articles: