hybrid_stack_manager 0.1.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 36

hybrid_stack_manager #

In hybrid scenarios where there are flutter pages and native pages, and they can jump to flutter/native at will. In other words, hybrid stack management would be the first important problem we should consider. This package can manage the hybrid stack and supports any jumping between flutter/native and native/flutter.

Architecture #

Snapshot #





Usage #

Add dependency in pubspec.yaml:


After getting the package using "flutter packages get",you can check the examples within the package to see how to use it.

Usage in iOS side #

1.Construct a navigationController as the rootWindow's rootViewController for later use when pushing.

2.Set the XURLRouter's nativeOpenUrlHandler where you can implement your own business related router logic,as below:

    [[XURLRouter sharedInstance] setNativeOpenUrlHandler:^UIViewController *(NSString *url,NSDictionary *query,NSDictionary *params){
        NSURL *tmpUrl = [NSURL URLWithString:url];
        if([@"ndemo" isEqualToString:tmpUrl.host]){
            return [XDemoController new];
        return nil;
  1. All scheme's query will be checked whehter to jump Flutter(flutter=true) or Native(flutter=false/nil)。 This is a universal logic applying in ios/android/flutter. As below:
void XOpenURLWithQueryAndParams(NSString *url,NSDictionary *query,NSDictionary *params){
    NSURL *tmpUrl = [NSURL URLWithString:url];
    UINavigationController *rootNav = (UINavigationController*)[UIApplication sharedApplication].delegate.window.rootViewController;
    if(![kOpenUrlPrefix isEqualToString:tmpUrl.scheme])
    if([[query objectForKey:@"flutter"] boolValue]){
        [[XFlutterModule sharedInstance] openURL:url query:query params:params];
    NativeOpenUrlHandler handler = [XURLRouter sharedInstance].nativeOpenUrlHandler;
        UIViewController *vc = handler(url,query,params);
            [rootNav pushViewController:vc animated:YES];

Usage in Android side #

1.Set the XURLRouter's appContextcontext with the ApplicationContext for later use when jumping.


2.Set XURLRouter's NativeRouterHandler with one always existing instance. This instance should implements XURLRouterHandler and implement method:openUrlWithQueryAndParams where you can implement your own business related router logic,as below:

  void setupNativeOpenUrlHandler(){
  public Class openUrlWithQueryAndParams(String url, HashMap query, HashMap params){
    Uri tmpUri = Uri.parse(url);
      return XDemoActivity.class;
    return null;

Usage in Flutter side #

1.Init a global key for later use to fetch a context and pass it to the Router. 2.Set the Router's routerWidgetHandler where Flutter side router logic is implemented,as below:

    Router.sharedInstance().routerWidgetHandler =
        ({RouterOption routeOption, Key key}) {
      if (routeOption.url == "hrd://fdemo") {
        return new FDemoWidget(routeOption, key: key);
      return null;
    return _singleton;

Attention #

1.In Flutter,the NavigatorState class located in flutter/lib/src/widgets/navigator.dart is modified by adding a getter function to fetch the history as below:

  List<Route<dynamic>> get history => _history;

2.In iOS,I reuse the XFlutterViewController singleton which is embedded in FlutterViewWrapperController with the help of addChildVC/removeFromParentVC。It is necessary to ensure that the viewWill/DidAppear/Disappear call could be passed from ParentVC Appear to ChildVC(Especially the viewWillAppear: and viewDidDisappear:)。

- (BOOL)shouldAutomaticallyForwardAppearanceMethods{
    return TRUE;


KyleWongdeMacBook-Pro:ios kylewong$ /Users/kylewong/Codes/Flutter/official/flutter/bin/flutter doctor -v
[✓] Flutter (Channel unknown, v0.9.6, on Mac OS X 10.14.1 18B57c, locale en-CN)
• Flutter version 0.9.6 at /Users/kylewong/Codes/Flutter/master/flutter
• Framework revision 13684e4f8e (4 weeks ago), 2018-10-02 14:15:17 -0400
• Engine revision f6af1f20ba
• Dart version 2.1.0-dev.6.0.flutter-8a919426f0

[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
• Android SDK at /Users/kylewong/Library/Android/sdk
• Android NDK at /Users/kylewong/Library/Android/sdk/ndk-bundle
• Platform android-28, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
• All Android licenses accepted.

[!] iOS toolchain - develop for iOS devices (Xcode 10.0)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 10.0, Build version 10A254a
• ios-deploy 1.9.2
! CocoaPods out of date (1.5.0 is recommended).
CocoaPods is used to retrieve the iOS platform side's plugin code that responds to your plugin usage on the Dart side.
Without resolving iOS dependencies with CocoaPods, plugins will not work on iOS.
For more info, see https://flutter.io/platform-plugins
To upgrade:
brew upgrade cocoapods
pod setup

[✓] Android Studio (version 3.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 29.1.1
• Dart plugin version 181.5656
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)

[✓] Connected device (2 available)
• SM G950U          • 988837355242375644                       • android-arm64 • Android 7.0 (API 24)

Though flutter beta v0.6.0 is used in my environment. In fact, this hybrid stack management logic works even in v0.3.1 and above.

Contact me #

Contact me

[0.0.1] - 2018-08-15 #

  • First tag, support hybrid stack management between native(ios/android) and flutter.

[0.0.2] - 2018-08-15 #

  • Change environment support(sdk&flutter)

[0.0.3] - 2018-08-21 #

  • Add License
  • Process an AssertError when using flutter v0.5.8+
  • Change all display tet into English

[0.0.4] - 2018-08-21 #

  • Change README.

[0.0.5] - 2018-09-05 #

  • Add TODO where developers may need to add their customized implementations for non-json-serializable objects into json-serializable ones.

[0.0.6] - 2018-09-25 #

  • Repository relocated.

[0.0.7] - 2018-10-31 #

  • Enable support to launch from flutter as the first page which mades it more flexible.
  • Fix a white screen problem resulted from gesture confliction when swiping to pop in iOS.
  • Add support to take screenshot from flutter side. It is asynchronous, henceforth, the native (iOS&Android) still use the old logic which is using native api and synchronous.

[0.1.0] - 2018-12-25 #

  • This new version only change the iOS side logic.
  • As Flutter1.0 has split FlutterEngine(engine) and FlutterViewController(display), remove the FlutterViewWrapperViewController and move some logic like route control from FlutterViewWrapperViewController to XFlutterViewController.
  • Taking snapshot is not needed anymore.

[0.1.1] - 2019-02-16 #

  • Change podspec.json to podspec, it will fix a Flutter/Flutter.h not found problem.


import 'package:flutter/material.dart';
import 'package:hybrid_stack_manager/hybrid_stack_manager_plugin.dart';

import 'app_config.dart';
import 'my_app.dart';

void main() async {
  HybridStackManagerPlugin plugin =
  Map args = await plugin.getMainEntryParams();
  runApp(new MyApp());
  if (args != null && args["url"] != null) {
    RouterOption routeOption = new RouterOption(
        url: args["url"], query: args["query"], params: args["params"]);
        routeOption: routeOption, animated: false);

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  hybrid_stack_manager: ^0.1.1

2. Install it

You can install packages from the command line:

with pub:

$ pub get

with Flutter:

$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:hybrid_stack_manager/hybrid_stack_manager.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Apr 7, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Health issues and suggestions

Fix lib/router.dart. (-76.86 points)

Analysis of lib/router.dart failed with 5 errors, 5 hints, including:

line 69 col 49: The getter 'history' isn't defined for the class 'NavigatorState'.

line 86 col 48: The getter 'history' isn't defined for the class 'NavigatorState'.

line 96 col 48: The getter 'history' isn't defined for the class 'NavigatorState'.

line 111 col 48: The getter 'history' isn't defined for the class 'NavigatorState'.

line 146 col 48: The getter 'history' isn't defined for the class 'NavigatorState'.

Document public APIs. (-0.02 points)

57 out of 59 API elements have no dartdoc comment.Providing good documentation for libraries, classes, functions, and other API elements improves code readability and helps developers find and use your API.

Format lib/utils.dart.

Run flutter format to format lib/utils.dart.

Maintenance issues and suggestions

No valid SDK. (-20 points)

The analysis could not detect a valid SDK that can use this package.

Support latest dependencies. (-10 points)

The version constraint in pubspec.yaml does not support the latest published versions for 1 dependency (path_provider).

Package is getting outdated. (-13.70 points)

The package was last published 59 weeks ago.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.48.0 <3.0.0
flutter 0.0.0
image ^2.0.0 2.1.12
path_provider ^0.4.0 0.4.1 1.6.5
Transitive dependencies
archive 2.0.13
args 1.6.0
charcode 1.1.3
collection 1.14.11 1.14.12
convert 2.1.1
crypto 2.1.4
meta 1.1.8
path 1.6.4
petitparser 3.0.2
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
xml 3.7.0 4.1.0