Flutter can be a standalone project, but in the case of existing projects the best approach is to mix and transition. This allows both the Native and the flutter code to coexist. The key is how the flutter starts the page and how the flutter interacts with the native.
This article uses Android as an example to show how to introduce Flutter in an existing project, start flutter, speed up flutter startup, and pass parameters.
Flutter was introduced into existing projects
Create a Flutter Module in your existing Android project. After you create a module, you will find that it is automatically dependent on the main module. Of course, this step will not be automatically implemented if other projects use the Flutter module. Therefore, register the Flutter module with setting.gradle as follows:
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir,
'flutter_module/.android/include_flutter.groovy'
))
include ':flutter_module'
Copy the code
Then rely on the main Module:
implementation project(path: ':flutter')
Copy the code
This allows for mixed development.
Start flutter page
A new Flutter Module automatically creates a main page. How does Native open this page?
First add to the manifest of the main Module:
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
Copy the code
Then use the code to open the Flutter home page
startActivity(FlutterActivity.createDefaultIntent(this))
Copy the code
So how do I open other pages?
For example, we create a new Flutter page second:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SecondPage extends StatefulWidget{
@override
State<StatefulWidget> createState(a) {
return_SecondPage(); }}class _SecondPage extends State<SecondPage>{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("test"),
),
body:Text("test")); }}Copy the code
Dart then registers the page in the main.dart App:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
routes: {
"second" : (BuildContext context) => SecondPage(), // You can also register in other ways}); }}Copy the code
This opens the page in Flutter with the following code:
Navigator.of(context).pushNamed("second");
Copy the code
On Android, you can open the page with the following code:
startActivity(FlutterActivity.withNewEngine().initialRoute("second").build(this))
Copy the code
accelerating
When opening the flutter page through the above code, a black screen will appear, which is not short and will affect the experience. This is because every time a new flutter engine is created (createDefaultIntent withNewEngine().build(launchContext)).
The official solution is to use Engine Cache, such as adding a cache to Appliation:
var flutterEngine = FlutterEngine(this)
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache.getInstance().put("main", flutterEngine)
Copy the code
Then change the startup to:
startActivity(FlutterActivity.withCachedEngine("main").build(this))
Copy the code
If you want to start other pages, such as Second, you need to continue adding the cache:
var flutterEngine2 = FlutterEngine(this)
flutterEngine2.navigationChannel.setInitialRoute("second")
flutterEngine2.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache.getInstance().put("second", flutterEngine2)
Copy the code
Note that the route is set by setInitialRoute. Then start:
startActivity(FlutterActivity.withCachedEngine("second").build(this))
Copy the code
With the cache Engine, the black screen time at startup is reduced to almost imperceptible (note that it may be slightly black the first time around).
Start the participation
We have opened the main and second pages without passing in parameters. What if we want to pass in some parameters necessary for initialization?
Currently, the Flutter framework does not encapsulate an API that carries parameters, which means that native jump flutter has no parameters. But our actual scene has such requirements, how to deal with?
There is no official API, so we have to find a way from route. First of all, change the way of registering route in app. Above, the form of routes map is directly used, and we change it to the form of onGenerateRoute RouteFactory, as follows:
onGenerateRoute: (RouteSettings settings) {
if(settings.name.startsWith("second")) {return MaterialPageRoute(builder: (BuildContext context) {
return SecondPage(settings.name);
});
}
else {
return MaterialPageRoute(builder: (BuildContext context) {
return Scaffold(
body: Center(
child: Text("page not found"),),); }); }},Copy the code
Settings. name is route, and since we want to add parameters after route, we can use the beginning to determine which page it is.
Note: In the example, the route URL was passed directly to the page. Instead, it should be resolved and passed to the page as a map.
Then modify the Second page:
class SecondPage extends StatefulWidget{
String url;
SecondPage(String url){
this.url = url;
}
@override
State<StatefulWidget> createState(a) {
return_SecondPage(); }}class _SecondPage extends State<SecondPage>{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("test"),
),
body:Text("test:${widget.url}")); }}Copy the code
There is no parsing here, the URL is displayed directly, the purpose is to pass the parameters in place.
Finally, use the following code in Native:
startActivity(FlutterActivity.withNewEngine().initialRoute("second? text=second test").build(this))
Copy the code
You can pass parameters.
This introduces another problem, because engine cache is not used in this startup. If engine cache is used, the route must be specified in advance to be cached in Appllication. The route is dynamically changed, so the two are in conflict, so we can’t speed up the startup in the case of parameter passing.
Since passing the parameter itself is not the behavior of the official API, the official Engine Cache does not support it. However, this problem is not impossible to solve. For example, the open flutter hybrid framework of The Idle fish, the flutter-boost, can easily implement the native to open the flutter page. However, there are a lot of things involved in flutter. I will use a separate article to explain how flutter-boost realizes parameter transfer and fast start.