Understanding Flutter Hybrid Stack: Architecture, Issues, and Solutions
This article examines Flutter's hybrid stack on Android, explaining its evolution, the problems caused by multiple engines and views, and reviewing community and official solutions such as Flutter Boost's view and engine reuse approaches with code examples.
This article reviews the Flutter hybrid stack from an Android perspective, tracing its evolution from version 1.0 to 1.9 and explaining why native‑Flutter coexistence is needed in large apps.
It defines what a hybrid stack is, describes the problems caused by multiple Flutter engines and views, and outlines the goal of mapping each Flutter page to an Android activity so that both stacks can be merged into a single navigation stack without performance loss.
The classic three‑layer Flutter architecture (Framework, Engine, Embedder) is introduced, with references to official documents such as "Flutter from loading to rendering", "The Engine architecture" and "Custom Flutter Engine Embedders".
In Android, the default implementation uses io.flutter.app.FlutterActivity and creates a separate FlutterView and FlutterNativeView for each page, leading to duplicated resources and memory usage. The relevant classes are listed below:
io.flutter.app.FlutterActivit
io.flutter.app.FlutterActivityDelegate
io.flutter.view.FlutterMain
io.flutter.view.FlutterView
io.flutter.view.FlutterNativeView
io.flutter.embedding.engine.dart.DartExecutor
io.flutter.embedding.engine.FlutterJNIThe article then examines two community solutions based on the Flutter Boost library.
Flutter Boost 0.0.4+ (FlutterView reuse) modifies the creation of FlutterView in FlutterActivityDelegate.onCreate to reuse a cached view. Representative initialization code:
FlutterBoostPlugin.init(new IPlatform() {
...
/**
* Get the main Activity that stays at the bottom of the stack.
*/
@Override
public Activity getMainActivity() {
if (MainActivity.sRef != null) {
return MainActivity.sRef.get();
}
return null;
}
...
});Key fragment from FlutterActivityDelegate.onCreate :
@Override
public void onCreate(Bundle savedInstanceState) {
// Get flutterView
flutterView = viewFactory.createFlutterView(activity);
// If null, create; otherwise reuse
if (flutterView == null) {
FlutterNativeView nativeView = viewFactory.createFlutterNativeView();
flutterView = new FlutterView(activity, null, nativeView);
flutterView.setLayoutParams(matchParent);
activity.setContentView(flutterView);
launchView = createLaunchView();
if (launchView != null) {
addLaunchView();
}
}
...
}Flutter Boost 0.1.5+ (FlutterEngine reuse) provides a callback to supply a shared BoostFlutterEngine . Example code:
FlutterBoost.init(new Platform() {
...
@Override
public IFlutterEngineProvider engineProvider() {
return new BoostEngineProvider() {
@Override
public BoostFlutterEngine createEngine(Context context) {
return new BoostFlutterEngine(context,
new DartExecutor.DartEntrypoint(
context.getResources().getAssets(),
FlutterMain.findAppBundlePath(context),
"main"), "/");
}
};
}
...
});In the corresponding BoostFlutterActivity the engine and view are created and attached:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFlutterEngine = createFlutterEngine();
mFlutterView = createFlutterView(mFlutterEngine);
setContentView(mFlutterView);
...
}
protected BoostFlutterEngine createFlutterEngine() {
return FlutterBoost.singleton().engineProvider().provideEngine(this);
}The official Flutter solution, introduced in the embedding package, recommends using FlutterEngineCache to share a single engine across activities. The activity creates a FlutterView via the delegate, which in turn creates a FlutterSplashView that displays a splash screen before the first frame.
View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Create FlutterView
flutterView = new FlutterView(host.getActivity(), host.getRenderMode(), host.getTransparencyMode());
// Create splash wrapper
flutterSplashView = new FlutterSplashView(host.getContext());
flutterSplashView.displayFlutterViewWithSplash(flutterView, host.provideSplashScreen());
return flutterSplashView;
}Overall, the article concludes that hybrid‑stack techniques have matured over the past year, offering developers multiple viable approaches—FlutterView reuse, Engine reuse, or the official embedding APIs—to integrate Flutter into existing native Android applications efficiently.
Further reading links are provided for deeper exploration of Flutter hybrid development, platform views, and channel communication.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.