FlutterBoost
repository·main·Indexed 27 days ago
https://github.com/alibaba/flutter_boostA hybrid solution for integrating Flutter into existing native Android, iOS, and HarmonyOS applications. It provides a unified routing mechanism to simplify the management of native and Flutter page stacks, along with a custom event passing API (BoostChannel) for communication between Flutter and native platforms.
What's inside flutter_boost
- FlutterBoost is a next-generation Flutter-Native hybrid solution. It is a Flutter plugin designed to provide easy hybrid integration for existing native applications. The core philosophy is to treat Flutter pages like WebViews, where FlutterBoost manages the mapping and navigation between Native and Flutter pages. Developers can focus on page names and parameters (similar to URLs) rather than the complexities of managing mixed page stacks.
Register a global lifecycle observer
mainTo monitor lifecycle events across the entire application, implement the
GlobalPageVisibilityObservermixin and register it usingPageVisibilityBinding.instance.addGlobalObserver. This is typically done in themain()function.Available lifecycle methods to override:
onBackground(Route route)onForeground(Route route)onPagePush(Route route)onPagePop(Route route)onPageHide(Route route)onPageShow(Route route)
void main() { /// Add global lifecycle observer PageVisibilityBinding.instance.addGlobalObserver(AppLifecycleObserver()); runApp(MyApp()); } /// Example implementation of a global observer class AppLifecycleObserver with GlobalPageVisibilityObserver { @override void onBackground(Route route) { super.onBackground(route); print("AppLifecycleObserver - onBackground"); } @override void onForeground(Route route) { super.onForeground(route); print("AppLifecycleObserver - onForground"); } @override void onPagePush(Route route) { super.onPagePush(route); print("AppLifecycleObserver - onPagePush"); } @override void onPagePop(Route route) { super.onPagePop(route); print("AppLifecycleObserver - onPagePop"); } @override void onPageHide(Route route) { super.onPageHide(route); print("AppLifecycleObserver - onPageHide"); } @override void onPageShow(Route route) { super.onPageShow(route); print("AppLifecycleObserver - onPageShow"); } }Implement Custom Flutter Binding and FlutterBoostApp
mainTo integrate FlutterBoost into your Dart code, you need to:
- Create a
CustomFlutterBindingthat mixes inBoostFlutterBinding. - Use
FlutterBoostAppas the root widget instead of a standardMaterialApporCupertinoApp. - Provide a
routeFactoryto handle route creation based onRouteSettings. - Provide an
appBuilder(optional) to wrap the home widget, ensuring thebuilderparameter is set to avoid issues withshowDialog.
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_boost/flutter_boost.dart'; void main() { // Must call this to control Boost status (resume/pause) CustomFlutterBinding(); runApp(MyApp()); } // Custom binding implementation class CustomFlutterBinding extends WidgetsFlutterBinding with BoostFlutterBinding {} class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { // Map route names to factory functions Map<String, FlutterBoostRouteFactory> routerMap = { 'mainPage': (RouteSettings settings, String uniqueId) { return CupertinoPageRoute( settings: settings, builder: (_) { Map<String, Object> map = settings.arguments as Map<String, Object> ; String data = map['data'] as String; return MainPage(data: data); }); }, // ... other routes }; Route<dynamic> routeFactory(RouteSettings settings, String uniqueId) { FlutterBoostRouteFactory func = routerMap[settings.name] as FlutterBoostRouteFactory; return func(settings, uniqueId); } Widget appBuilder(Widget home) { return MaterialApp( home: home, builder: (_, __) { return home; }, ); } @override Widget build(BuildContext context) { return FlutterBoostApp( routeFactory, appBuilder: appBuilder, ); } }- Create a
Install FlutterBoost on Android
mainFollow these steps to integrate FlutterBoost into an Android project:
Configure
settings.gradle: Reference the Flutter module by adding the following code to include the.androiddirectory and the module project:Update
app/build.gradle: Add the dependencies for the flutter module and the flutter_boost project:Update
AndroidManifest.xml: AddFlutterBoostActivityand theflutterEmbeddingmeta-data inside the<application>tag.Initialize in
Applicationclass: CallFlutterBoost.instance().setup()inonCreateand implement theFlutterBoostDelegateto handlepushNativeRouteandpushFlutterRoute.
// settings.gradle setBinding(new Binding([gradle: this])) evaluate(new File( settingsDir.parentFile, 'flutter_module/.android/include_flutter.groovy' )) include ':flutter_module' project(':flutter_module').projectDir = new File('../flutter_module')// app/build.gradle implementation project(':flutter') implementation project(':flutter_boost')<!-- AndroidManifest.xml --> <activity android:name="com.idlefish.flutterboost.containers.FlutterBoostActivity" android:theme="@style/Theme.AppCompat" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" > </activity> <meta-data android:name="flutterEmbedding" android:value="2"> </meta-data>// Application.java public class App extends Application { @Override public void onCreate() { super.onCreate(); FlutterBoost.instance().setup(this, new FlutterBoostDelegate() { @Override public void pushNativeRoute(FlutterBoostRouteOptions options) { Intent intent = new Intent(FlutterBoost.instance().currentActivity(), YourTargetAcitvity.class); FlutterBoost.instance().currentActivity().startActivityForResult(intent, options.requestCode()); } @Override public void pushFlutterRoute(FlutterBoostRouteOptions options) { Intent intent = new Intent(FlutterBoost.instance().currentActivity(), FlutterBoostActivity.class); // Use CachedEngineIntentBuilder for more complex configurations Intent detailedIntent = new FlutterBoostActivity.CachedEngineIntentBuilder(FlutterBoostActivity.class) .backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent) .destroyEngineWithActivity(false) .uniqueId(options.uniqueId()) .url(options.pageName()) .urlParams(options.arguments()) .build(FlutterBoost.instance().currentActivity()); FlutterBoost.instance().currentActivity().startActivity(detailedIntent); } }, engine -> { }); } }Create a Custom FlutterPage in OHOS
mainTo host a Flutter view, create a component (e.g.,
MyFlutterPage) that manages aFlutterBoostEntry.Key steps:
- In
aboutToAppear, initializeFlutterBoostEntryusinggetContext(this)androuter.getParams(). CallflutterEntry.aboutToAppear()and retrieve the view viaflutterEntry.getFlutterView(). - Implement lifecycle forwarding: call
flutterEntry.onPageShow(),onPageHide(), andaboutToDisappear()within the corresponding component lifecycle methods. - In the
buildmethod, use theFlutterPagecomponent passing theviewIdfrom theflutterView. - To handle back button interception, call
FlutterBoost.getInstance().getPlugin()?.onBackPressed()inonBackPress().
@Entry @Component struct MyFlutterPage { private flutterEntry: FlutterBoostEntry | null = null; private flutterView?: FlutterView aboutToAppear() { this.flutterEntry = new FlutterBoostEntry(getContext(this), router.getParams()); this.flutterEntry.aboutToAppear(); this.flutterView = this.flutterEntry.getFlutterView(); hilog.info(0x0000, "Flutter", "Index aboutToAppear==="); } aboutToDisappear() { hilog.info(0x0000, "Flutter", "Index aboutToDisappear==="); this.flutterEntry?.aboutToDisappear() } onPageShow() { hilog.info(0x0000, "Flutter", "Index onPageShow==="); this.flutterEntry?.onPageShow() } onPageHide() { hilog.info(0x0000, "Flutter", "Index onPageHide==="); this.flutterEntry?.onPageHide() } build() { Stack() { FlutterPage({ viewId: this.flutterView?.getId() }) } } // Intercept back key onBackPress(): boolean | void { FlutterBoost.getInstance().getPlugin()?.onBackPressed(); return true; } }- In
Initialize FlutterBoost on OHOS
mainTo initialize FlutterBoost, your
UIAbilityshould implementFlutterBoostDelegate. You must callFlutterBoost.getInstance().setup(ideally withinonWindowStageCreate).It is highly recommended to include
GeneratedPluginRegistrant.getPlugins()in theoptionsBuilderto ensure Flutter plugins are correctly registered. For a version that returns a Promise, useFlutterBoost.getInstance().setupSync.export default class EntryAbility extends UIAbility implements FlutterBoostDelegate { // FlutterBoostDelegate override pushNativeRoute(options: FlutterBoostRouteOptions) { } // FlutterBoostDelegate override pushFlutterRoute(options: FlutterBoostRouteOptions) { router.pushUrl({ url: 'pages/MyFlutterPage', params: { uri: options.getPageName(), params: options.getArguments(), }, }).then(() => { console.info('Succeeded in jumping to the second page.') }) } onWindowStageCreate(windowStage: window.WindowStage): void { // Initialize startup options (recommended to include GeneratedPluginRegistrant.getPlugins()) const optionsBuilder: FlutterBoostSetupOptionsBuilder = new FlutterBoostSetupOptionsBuilder() .setPlugins(GeneratedPluginRegistrant.getPlugins()); FlutterBoost.getInstance().setup(this, this.context, () => { // Engine initialized successfully }, optionsBuilder.build()) } }Support Multiple Flutter Instances in Tabs (OHOS)
mainTo allow multiple Flutter instances to coexist across different tabs in an OHOS application:
- Maintain an array of
FlutterBoostEntryobjects in your parent component. - In
aboutToAppear, initialize eachFlutterBoostEntrywith its respectiveuriand store them in the array. - In the
Tabscomponent'sonChangelistener, manually manage the lifecycle of the entries. When switching tabs, callaboutToAppear()andonPageShow()for the entering entry, andonPageHide()for the exiting entry. - In the tab content rendering, use
FlutterPage({ viewId: entry.getFlutterView()?.getId() })to display the specific instance.
// Inside a Tabs component onChange .onChange((index: number) => { this.currentIndex = index; if (this.currentIndex == 1) { this.flutterEntries[0]?.aboutToAppear(); this.flutterEntries[0]?.onPageShow(); this.flutterEntries[1]?.onPageHide(); } else if (this.currentIndex == 2) { this.flutterEntries[1]?.aboutToAppear(); this.flutterEntries[1]?.onPageShow(); this.flutterEntries[0]?.onPageHide(); } })- Maintain an array of
Add FlutterBoost dependency to your Flutter project
mainTo add FlutterBoost to your project, open your
pubspec.yamlfile and add the following dependency using the specific git reference for version 4.6.5:flutter_boost: git: url: 'https://github.com/alibaba/flutter_boost.git' ref: '4.6.5'Install FlutterBoost via pubspec.yaml
mainTo add FlutterBoost to your Flutter project, add the following dependency to your
pubspec.yamlfile. It is recommended to use the specific git reference for the version you require.flutter_boost: git: url: 'https://github.com/alibaba/flutter_boost.git' ref: '4.6.5'Configure screen orientation for Flutter ViewControllers on iOS
mainSetting orientation for a
FlutterViewControllerrequires coordination between the NativeNavigationControllerand the Dart layer:- Native (Objective-C): Override
shouldAutorotateandsupportedInterfaceOrientationsin yourNavigationControllerto delegate orientation decisions to the top view controller if it is aFlutterViewController.
-(BOOL)shouldAutorotate { return YES; } -(UIInterfaceOrientationMask)supportedInterfaceOrientations { id currentViewController = self.topViewController; if ([currentViewController isKindOfClass:[FlutterViewController class]]){ return [currentViewController supportedInterfaceOrientations]; } return UIInterfaceOrientationMaskAll; }- Dart: Since
SystemChrome.setPreferredOrientationsis global and can be overwritten when newFlutterViewControllersare created in a hybrid stack, you must callSystemChrome.setPreferredOrientationswithin thebuildmethod of every Dart page to ensure the desired orientation is maintained.
#!objc -(BOOL)shouldAutorotate { // id currentViewController = self.topViewController; // // if ([currentViewController isKindOfClass:[FlutterViewController class]]) // return [currentViewController shouldAutorotate]; return YES; } -(UIInterfaceOrientationMask)supportedInterfaceOrientations { id currentViewController = self.topViewController; if ([currentViewController isKindOfClass:[FlutterViewController class]]){ NSLog("[XDEBUG]----fvc supported:%ld\n",[currentViewController supportedInterfaceOrientations]); return [currentViewController supportedInterfaceOrientations]; } return UIInterfaceOrientationMaskAll; }- Native (Objective-C): Override
Initialize FlutterBoost in Android Application
mainIn your
Applicationclass, callFlutterBoost.instance().setup(...). You must implement aFlutterBoostDelegateto handle two types of routing:pushNativeRoute: Triggered when a Flutter page wants to open a Native activity.pushFlutterRoute: Triggered when a Native page wants to open a Flutter page. UseFlutterBoostActivity.CachedEngineIntentBuilderto build the intent for Flutter routes.
public class MyApplication extends FlutterApplication { @Override public void onCreate() { super.onCreate(); FlutterBoost.instance().setup(this, new FlutterBoostDelegate() { @Override public void pushNativeRoute(String pageName, HashMap<String, String> arguments) { Intent intent = new Intent(FlutterBoost.instance().currentActivity(), NativePageActivity.class); FlutterBoost.instance().currentActivity().startActivity(intent); } @Override public void pushFlutterRoute(String pageName, HashMap<String, String> arguments) { Intent intent = new FlutterBoostActivity.CachedEngineIntentBuilder(FlutterBoostActivity.class, FlutterBoost.ENGINE_ID) .backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.opaque) .destroyEngineWithActivity(false) .url(pageName) .urlParams(arguments) .build(FlutterBoost.instance().currentActivity()); FlutterBoost.instance().currentActivity().startActivity(intent); } }, engine -> { engine.getPlugins(); }); } }Navigate between Flutter and Native (Android)
mainIn Android, use
FlutterBoost.instance()to control page transitions.- Open a Flutter page:
FlutterBoost.instance().open("pageName", params); - Close a Flutter page:
FlutterBoost.instance().close("uniqueId");
Note: Ensure your
AndroidManifest.xmlis configured withflutterEmbedding=2and includes theFlutterBoostActivity.- Open a Flutter page: