The Flutter hybrid development family includes the following:
- Embed native View-Android
- Embed native View-ios
- Communicate with native -MethodChannel
- Communicate with native -BasicMessageChannel
- Communicate with native -EventChannel
- Add Flutter to Android Activity
- Add Flutter to Android Fragment
- Add Flutter to iOS
Share one article every weekday, welcome to follow, like and forward.
Create a Flutter Module
Flutter can be embedded into Android native projects either as source code or as an AAR. The integration process can be done using Android Studio or manually. Android Studio is highly recommended.
First create an Android project and create an empty Activity:
After the Android project is created, add the Flutter Module using Android Studio. In the Android native project, go to File > New > New Module… Create Flutter Module
Note: Android Studio version 3.5 and later, the Flutter IntelliJ Plugin version 42 and later.
Select Flutter Module in the dialog box that pops up to select the Module type and click Next.
To set the Project name of the Flutter Module, the Flutter SDK, and so on, click Next:
Set the package name for the Flutter Module and click Finish:
After compilation, the code for the Flutter module will be generated in the current App directory with the following structure:
Start page to load the Flutter
Load the Flutter page into MainActivity (the default startup page) and modify the MainActivity:
package com.flutter.androidflutter
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity(a)Copy the code
You read that right, just make MainActivity inherit from FlutterActivity.
Note: the package name of FlutterActivity is IO flutter. Embedding. Android. FlutterActivity
Jump to the Flutter page
MainActivity (default startup page) add a button to redirect to a new page that loads the Flutter. The MainActivity code is as follows:
package com.flutter.androidflutter
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
startActivity(Intent(this,SecondFlutterActivity::class.java))
}
}
}
Copy the code
The SecondFlutterActivity code looks like this:
package com.flutter.androidflutter
import io.flutter.embedding.android.FlutterActivity
class SecondFlutterActivity:FlutterActivity(a)Copy the code
Register this Activity in androidmanifest.xml:
<? The XML version = "1.0" encoding = "utf-8"? > <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.flutter.androidflutter"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> ... <activity android:name=".SecondFlutterActivity"/> </application> </manifest>Copy the code
SecondFlutterActivity simply inherits FlutterActivity, in which case you can also use FlutterActivity directly:
startActivity(Intent(this, FlutterActivity::class.java))
Copy the code
Or:
startActivity(FlutterActivity.createDefaultIntent(this))
Copy the code
Register FlutterActivity in Androidmanifest.xml:
<activity android:name="io.flutter.embedding.android.FlutterActivity"/>
Copy the code
The effect is the same as above.
FlutterActivity loads the main method of lib/main.dart in the Flutter Module. If there are multiple Flutter pages, how can I specify the jump? The OnePage code is as follows:
class OnePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text('This is the One page'),),); }}Copy the code
FlutterActivity specifies that the loading page needs to use named routes. MyApp is modified as follows:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'one_page':(context){
return OnePage();
},
'two_page':(context){
return TwoPage();
}
},
home: MyHomePage(title: 'Flutter Demo Home Page')); }}Copy the code
Click on the Flutter page to load the OnePage page:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
startActivity(
FlutterActivity
.withNewEngine()
.initialRoute("one_page")
.build(this)}}}Copy the code
Engine cache
When loading the FlutterActivity page, there was obviously a black screen for a period of time, during which the FlutterEngine was started. The startup time of the Flutter engine was different on different mobile phones, and the better the performance of the Flutter engine was, the shorter it was. Each FlutterActivity page also starts an engine, so it is strongly recommended not to create multiple FlutterActivity (or start multiple instances of FlutterActivity) in a single project, otherwise memory will get bigger and bigger. Here is the memory variation diagram for creating an instance of FlutterActivity every 3 seconds:
To reduce the latency of FlutterActivity pages and the memory growth of multiple FlutterActivity instances, we can use the Flutter engine cache. Start the Flutter engine before starting FlutterActivity, and then load the page using the cached engine, usually in Application:
class MyApplication : Application() {
lateinit var flutterEngine: FlutterEngine
override fun onCreate(a) {
super.onCreate()
flutterEngine = FlutterEngine(this)
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache
.getInstance()
.put("engine_id", flutterEngine)
}
}
Copy the code
Engines that use caching:
startActivity(
FlutterActivity
.withCachedEngine("engine_id")
.build(this))Copy the code
On the same phone, the effect is very clear, with the black screen time greatly reduced, but there is still a brief black screen.
Note that when using the cache engine, it is not the life cycle of the FlutterActivity (or FlutterFragment), but the life cycle of the entire App (created and destroyed in the Application). Of course, it can also be destroyed in advance:
flutterEngine.destroy()
Copy the code
In addition, the debug and release versions of the project have a great impact on performance. If you want to test its performance, you must test it under release.
Using the new engine above, you can specify FlutterActivity (or FlutterFragment) to configure the initial route, but you cannot configure the initial route in FlutterActivity (or FlutterFragment) with the cache engine. Since the cache engine is already up and running, you can specify its initial route when you start the cache engine:
flutterEngine = FlutterEngine(this)
flutterEngine.navigationChannel.setInitialRoute("one_page")
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache
.getInstance()
.put("engine_id", flutterEngine)
Copy the code
What if a cache engine is used to specify different routes in FlutterActivity (or FlutterFragment)? A method channel needs to be created, and the flutter receives specific messages to switch between different routes.
communication
Lao Meng Flutter blog (330 controls usage + practical primer series) : laomengit.com