Reference Documents:

  • Integrate the Flutter Module into the Android project
  • flutter add_to_app sample

Before we begin, we need to look at the four project structures of FLUTTER

  • Application: Pure Flutter application
  • Plugin: Native Plugin for Flutter
  • Package: Pure DART plug-in
  • Module: Natively integrates the Flutter module

Integrate Flutter into the Android project

Run the following command in the native app directory:

flutter create -t module –org com.example flutter_lib

The following files are generated under the directory:We need to integrate the generated Flutter Module into our native application in two ways:

  • Aar depend on
  • Source dependent

1. Integration of Flutter Module

1. Aar dependencies

In the flutter_lib directory, we run the command:

flutter build aar

It’s nice that Flutter tells us on the command line how to integrate an AAR with native applications

Advantages:

  • The advantage of relying on an AAR package that contains Flutter artifacts is that other students who do not develop Flutter do not have to configure the Flutter environment, just like any other module package

2. Source code dependency

Open the setting.gradle file for the native project:

include ':app'
rootProject.name = "NativeToFlutter"

// Add the following code
setBinding(new Binding([gradle: this]))                                 
evaluate(new File(                                                      
        'flutter_lib/.android/include_flutter.groovy'                          
))
include ':flutter_lib'
Copy the code

Build. Gradle relies on the Flutter Module module in the app project

dependencies {
  implementation project(':flutter')
}
Copy the code

Disadvantages:

  • The need for a FLUTTER environment, and inconsistent developer environments, results in integration reporting various errors due to inconsistent versions

2. Native access to the Flutter page

The Flutter dependencies provide FlutterActivity to load flutter pages directly. We just need to configure this Activity in the manifest file:

<activity
  android:name="io.flutter.embedding.android.FlutterActivity"
  android:theme="@style/LaunchTheme"
  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
  android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"
  />
Copy the code

StartActivity where you want to open the flutter page:

 val intent = FlutterActivity
            .withNewEngine() 
            // Background color, transparent or opaque
            .backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
            // Specify the route home page to jump to
            .initialRoute("home")
            .build(this)
startActivity(intent)
Copy the code

3. Explicitly jump to the Flutter page

A Flutter provides an initialRoute for the native layer to jump to the specified route page corresponding to the Flutter. Officially, this route is limited:

The Dart entry specified is invalid when building a FlutterFragment with a preheated FlutterEngine. The preheated FlutterEngine already executes an entry function. Only FlutterEngine can explicitly select entries while warming up.

So, we must create a new engine with withNewEngine to open a page:

 val intent = FlutterActivity
            .withNewEngine() 
            // Redirect to the home routing page
            .initialRoute("home")
            .build(this)
startActivity(intent)
Copy the code

Due to the long time required to initialize the engine, and the fact that the specified route is opened, this is not ideal

4. EntryPoint

When we open a flutter page, by default, we start with the main function of the flutter. If we have multiple independent flutter modules for the native layer to open, this will result in all our independent flutter modules being concentrated in the main function. The module page is then routed. We have already shown that the performance of the flutter engine is poor. If the Flutter engine is initialized first, the routing effect will be invalid.

We can specify the entry point of a flutter page that we want to jump to. This function can be used to pre-initialize the engine without changing the page opening. It is simple to use:

void main(a) => runApp(MyApp(Colors.blue));

@pragma('vm:entry-point')
void home(a) => runApp(HomePage(Colors.green));
Copy the code

There is only a pragma annotation compared to the main method, and the method name home is entryPoint.

In the native layer we can write:

// Initialize the Flutter engine for the home page in application
val dartEntryPoint = DartExecutor.DartEntrypoint(
  FlutterInjector.instance().flutterLoader().findAppBundlePath(), "home"
)
val engineId = "home_engine_id"
val engine = enginesGroup.createAndRunEngine(app, engineId) // Create engine
FlutterEngineCache.getInstance().put(engineId, engine) // Cache engine by engine ID
    
// Bind entryPoint to a flutter page embedded in the native page
class MainFlutterActivity : AppCompatActivity(a){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_my_flutter)

        val flutterFragment = FlutterFragment
            	// Specify the engineId of the cache
                .withCachedEngine("home_engine_id")
                .build<FlutterFragment>()

        supportFragmentManager.beginTransaction()
            .add(R.id.flutter_container, flutterFragment)
            .commit()
    }
}

Copy the code

In this case, the native layer can directly open MainFlutterActivity, the effect is as follows:

5, the flutter thermal overload

When natively accessing the Flutter module, we expect the native project to run in the same way as flutter application development, debugging the Flutter code in real time. Flutter provides us with the flutter attach command to debug the flutter page. We just need to run this command and enter the project into the flutter page to debug:

We can change the Flutter code and type the commands specified, for example r, to hot reload the current page

6, summary

We can summarize this by drawing a dependency graph:

The current DEMO’s FLUTTER code is directly coded in the Flutter Module, which is not suitable for team development. Don’t forget that Flutter provides four project structures. We can use plugin and Package modules for component-based development. Then integrate the component dependencies into the Flutter Module so that they do not interfere with other member codes

Source demo: github.com/MRwangqi/Na…