Zhou Jianhua: Wedoctor mobile terminal diagnosis and treatment team, like reading and exercise Android program ape
preface
The main new features that Flutter2 brings are the stabilization of Null security, the announcement of stable desktop and Web support, and the most notable add-to-App updates that improve the mixed development experience of previous Flutter2 versions. The so-called add-to-app is a great way to Add the Flutter to existing iOS and Android applications to take advantage of the Flutter and reuse the Flutter code on both mobile platforms while still retaining the existing native code base. Before the emergence of this solution, similar third-party support was flutter_boost, Flutter_thrio, etc., but these solutions faced the following problems: Unofficial support has to be adapted from one release to the next, and with Flutter’s current rate of update, there are likely to be significant changes from one quarterly release to another, so intrusive frameworks like this can easily become a bottleneck if they are not maintained or maintained in a timely manner.
Flutter2 multi-engine hybrid development basic usage
Create an Android native project (skip the Android native project creation process)
Introduce the Flutter Module into the Android project using File -> New- > New Module… -> Select the Flutter Module, then specify a Module name, fill in the relevant information, click OK and wait for Gradle Sync to complete.
Android project integrates the Flutter Module
1) Create a FlutterEngineGroup object. FlutterEngineGroup can be used to manage multiple FlutterEngine objects. Multiple FlutterEngines can share resources. In this way, multiple FlutterEngines will occupy relatively few resources. The FlutterEngineGroup needs to be created in the Application onCreate method.
package com.zalex.hybird;
import android.app.Application;
import io.flutter.embedding.engine.FlutterEngineGroup;
public class WYApplication extends Application {
public FlutterEngineGroup engineGroup;
@Override
public void onCreate(a) {
super.onCreate();
// Create the FlutterEngineGroup object
engineGroup = new FlutterEngineGroup(this); }}Copy the code
2) Create WYFlutterEngineManager cache management class, and obtain the cached FlutterEngine from it through the FlutterEngineCache cache class. If not, Create the DartEntrypoint object with findAppBundlePath and entryPoint. FindAppBundlePath is the default flutter_assets directory. Entrypoint is actually the name of the launch method in the DART code; You bind the runApp method in dart, create a FlutterEngine with the createAndRunEngine method, and cache it.
public class WYFlutterEngineManager {
public static FlutterEngine flutterEngine(Context context, String engineId, String entryPoint) {
// 1. Obtain FlutterEngine from the cache
FlutterEngine engine = FlutterEngineCache.getInstance().get(engineId);
if (engine == null) {
// If there is no FlutterEngine in the cache
// 1. Create FlutterEngine and execute entryPoint
WYApplication app = (WYApplication) context.getApplicationContext();
DartExecutor.DartEntrypoint dartEntrypoint = new DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(), entryPoint);
engine = app.engineGroup.createAndRunEngine(context, dartEntrypoint);
// 2. Save to the cache
FlutterEngineCache.getInstance().put(engineId, engine);
}
returnengine; }}Copy the code
Activity binds the Flutter engine entry
public class WYFlutterActivity extends FlutterActivity implements EngineBindingsDelegate {
private WYFlutterBindings flutterBindings;
@Override
protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
flutterBindings = new WYFlutterBindings(this,SingleFlutterActivity.class.getSimpleName(),"main".this);
flutterBindings.attach();
}
@Override
protected void onDestroy(a) {
super.onDestroy();
flutterBindings.detach();
}
@Override
public FlutterEngine provideFlutterEngine(@NonNull @NotNull Context context) {
return flutterBindings.getEngine();
}
@Override
public void onNext(a) {
Intent flutterIntent = new Intent(this, MainActivity.class); startActivity(flutterIntent); }}Copy the code
Fragment binds the flutter engine entry
int engineId = engineId ;// Customize the engine Id
int fragmentId = 1233444;// Customize FragmentId
FrameLayout flutterContainer = new FrameLayout(this);
root.addView(flutterContainer);
flutterContainer.setId(containerId);
flutterContainer.setLayoutParams(new LinearLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT,
1.0 f
));
WYFlutterBindings flutterBindings = new WYFlutterBindings(this."WYTopFragment"."fragmentMain".this);
FlutterEngine engine = bottomBindings.getEngine();
FlutterEngineCache.getInstance().put(engineId+"", engine);
Fragment flutterFragment =FlutterFragment.withCachedEngine(engineId+"").build();
fragmentManager
.beginTransaction()
.add(containerId, flutterFragment)
.commit();
Copy the code
3) The engine entry of the Flutter module is bound. All engine entries except the main entry need to be annotated with @pragma(‘ VM :entry-point’)
void main() => runApp(MyApp(Colors.blue));
@pragma('vm:entry-point')
void fragmentMain() => runApp(CustomApp(Colors.green));
Copy the code
Flutter2 multi-engine hybrid development vs. single-engine hybrid development
1. The Multi-engine Solution is the Flutter API has always been supported. You can create multiple engines and render multiple different interfaces independently, but each time you start a Flutter engine, you have a separate engine. Through the test, we can find that one engine is 40M, creating 10 engines consumes 235M, which is a lot of memory, which is not acceptable in development.
2. Due to the multi-engine problem with the previous version of the Flutter, the industry has generally reused the ISOLATE or engine to solve the problem. The most influential are single-engine browser solutions such as FlutterBoost and Thrio. The Activity/ViewController is used as the browser hosting the Dart page, detach/attach the single Engine when the page is changed, and notify the Dart layer of the page change to realize the reuse of Engine. As only one Engine singleton is created and only one ISOLATE is created, the Dart layer communicates and shares resources, and the memory consumption is significantly reduced. However, the single-engine implementation relies on modifying the official IO. Flutter package, making a relatively large structural change to the Flutter framework.
3. Since Flutter 2, FlutterEngineGroup was used to create a new Engine under multiple engines. Officially, the memory loss was only 180K. This enables the Engine to share the GPU context, glyph, and isolate Group snapshot, resulting in faster initial speeds and lower memory usage.
4. The differences between the construction engine of Flutter 2 and Flutter 1:
Flutter1 engine creation
//Android
val engine = FlutterEngine(this)
engine.dartExecutor.executeDartEntrypoin(DartExecutor.DartEntrypoint.createDefault())
FlutterEngineCache.getInstance().put(1,engine)
val intent = FlutterActivity.withCacheEngine(1).build(this)
Copy the code
//iOS
let engine = FlutterEngine()
engine.run()
let vc = FlutterViewController(engine:engine,nibName:nil,bundle:nil)
Copy the code
Fluter2 engine creation
//Android
val engineGroup = FlutterEngineGroup(context)
val engine1 = engineGroup.createAndRunDefaultEngine(context)
valengine2 = engineGroup.createAndRunEngine(context,DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBun dlePath(),"anotherEntrypoint"))
Copy the code
//iOS
let engineGroup = FlutterEngineGroup(name:"example",project:nil)
let engine1 = engineGroup.makeEngine(withEntrypoint:nil,libraryURI:nil)
let engine2 = engineGroup.makeEngine(withEntrypoint:"anotherEntrypoint",libraryURI:nil)
Copy the code
5. Comparison of the hybrid development scheme of Flutter
6. Pros and cons of the Flyweight multi-engine versus single-engine
Afterword.
In this article, we describe the multi-engine use of the Flutter 2, the differences between multi-engine mixed development and single-engine mixed development, and the pros and cons. In the next section, we will learn how the multi-engine implementation of the Flutter 2 works.