FlutterBoost简单使用介绍

在使用flutter混合开发中,免不了flutter和原生native页面的相互跳转和通信,flutterboost就是闲鱼团队开发的一个可复用的插件,旨在把Flutter容器做成浏览器的感觉。填写一个页面地址,然后由容器去管理页面的绘制。在Native侧我们只需要关心如果初始化容器,然后设置容器对应的页面标志即可。

准备工作

  • Flutter项目
    在pubspec.yaml中添加以下依赖项:
flutter_boost: ^0.0.400

将init代码添加到Dart的app首页面;

void main (){
  runApp(App());
}

class App extends StatefulWidget{
  @override
  _MyAppState createState() => _MyAppState();

}

class _MyAppState extends State<App>{


  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    ///register page widget builders,the key is pageName
    FlutterBoost.singleton.registerPageBuilders({
      'first': (pageName, params, _) => FirstRouteWidget(),
      'second': (pageName, params, _) => SecondRouteWidget(),
      'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params),

      ///可以在native层通过 getContainerParams 来传递参数
      'flutterPage': (pageName, params, _) {
        print("flutterPage params:$params");

        return FlutterRouteWidget();
      },
    });

    ///query current top page and load it
    FlutterBoost.handleOnStartPage();
  }

  @override
  Widget build(BuildContext context) =>MaterialApp(
    title: "Flutter Boost demo",
    builder: FlutterBoost.init(),
    home: Container(),
  );

}
  • Android工程
    在Application.onCreate()中初始化FlutterBoost
public class MyApplication extends FlutterApplication {
    @Override
    public void onCreate() {
        super.onCreate();
        FlutterBoostPlugin.init(new IPlatform() {
            @Override
            public Application getApplication() {
                return MyApplication.this;
            }

            /**
             * get the main activity, this activity should always at the bottom of task stack.
             */
            @Override
            public Activity getMainActivity() {
                return MainActivity.sRef.get();
            }

            @Override
            public boolean isDebug() {
                return false;
            }

            /**
             * start a new activity from flutter page, you may need a activity router.
             */
            @Override
            public boolean startActivity(Context context, String url, int requestCode) {
                return PageRouter.openPageByUrl(context,url,requestCode);
            }

            @Override
            public Map getSettings() {
                return null;
            }
        });
    }

里面的PageRouter是在Android本地工程中定义的一个页面路由跳转类,比较简单就是一个根据URL来跳转到指定activity的配置类,代码如下

public class PageRouter {

    public static final String NATIVE_PAGE_URL = "sample://nativePage";
    public static final String FLUTTER_PAGE_URL = "sample://flutterPage";
    public static final String FLUTTER_FRAGMENT_PAGE_URL = "sample://flutterFragmentPage";

    public static boolean openPageByUrl(Context context, String url) {
        return openPageByUrl(context, url, 0);
    }

    public static boolean openPageByUrl(Context context, String url, int requestCode) {
        try {
            if (url.startsWith(FLUTTER_PAGE_URL)) {
                context.startActivity(new Intent(context, FlutterPageActivity.class));
                return true;
            } else if (url.startsWith(FLUTTER_FRAGMENT_PAGE_URL)) {
                context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
                return true;
            } else if (url.startsWith(NATIVE_PAGE_URL)) {
                context.startActivity(new Intent(context, NativePageActivity.class));
                return true;
            } else {
                return false;
            }
        } catch (Throwable t) {
            return false;
        }
    }
}

IOS平台怎么集成就不介绍了,因为没开发过IOS,如果需要的话可以去咸鱼官方找找怎么集成。

简单解析

首先介绍一下在Dart中使用flutterboost中打开一个页面:

FlutterBoost.singleton.openPage("pagename", {}, true);

关闭页面:

FlutterBoost.singleton.closePageForContext(context);

之前说过在flutterboost中旨在通过一个URL去打过一个页面,不管这个页面是一个flutter页面还是一个native页面,那它是怎么做到的呢?回头看看上面的代码

  • 打开Flutter页面

我们可以看到在Dart中创建_MyAppState这个widget的时候有下面这段代码

FlutterBoost.singleton.registerPageBuilders({
      'first': (pageName, params, _) => FirstRouteWidget(),
      'second': (pageName, params, _) => SecondRouteWidget(),
      'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params),

      ///可以在native层通过 getContainerParams 来传递参数
      'flutterPage': (pageName, params, _) {
        print("flutterPage params:$params");

        return FlutterRouteWidget();
      },
    });

上面的代码其实就是在将原生的flutter页面注册到flutterboost中,以key,value的形式,其中key就是页面名,value就是目标flutter页面,所以上面的代码在dart中就可以通过”second”这个url来打开SecondRouteWidget这个flutter页面,具体调用代码如下:

body: Center(
        child: RaisedButton(
          child: Text('Open second page'),
          onPressed: () {
            FlutterBoost.singleton.openPage("second", {}, animated: true);
          },
        ),
      ),);

可以看到FlutterBoost就是通过”second”这个url来打开flutter页面的,所以我们可以在一开始的app的widget的定义中把所有的flutter以键值对的形式都注册到FlutterBoost中,在之后就可以通过key来打开相应的flutter页面了。

  • 打开native页面

    仍然是讲Android的,IOS的可自行百度哈,上面的代码我们在application的oncreate中有初始化FlutterBoostPlugin,里面比较关键的是这个方法:
@Override
            public boolean startActivity(Context context, String url, int requestCode) {
                Debuger.log("startActivity url="+url);

                return PageRouter.openPageByUrl(context,url,requestCode);
            }

当在Dart中调用FlutterBoost.singleton.openPage(“pagename”, {}, true);这个方法打开的页面是一个native页面的时候就会回调到上面的那个方法中,可以看到会传过来一个url,接着就是使用我们自己定义的路由页面PageRouter根据指定的url来打开相应的native页面了。比如下面这样:

public static boolean openPageByUrl(Context context, String url, int requestCode) {
        try {
            if (url.startsWith(FLUTTER_PAGE_URL)) {
                context.startActivity(new Intent(context, FlutterPageActivity.class));
                return true;
            } else if (url.startsWith(FLUTTER_FRAGMENT_PAGE_URL)) {
                context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
                return true;
            } else if (url.startsWith(NATIVE_PAGE_URL)) {
                context.startActivity(new Intent(context, NativePageActivity.class));
                return true;
            } else {
                return false;
            }
        } catch (Throwable t) {
            return false;
        }
    }

可以看到在native的Android工程中就是根据FlutterBoost传回来的url来打开指定的activity的。其实现在有个问题,我们看到原生的flutter页面有在FlutterBoost注册,然后才能根据注册的url找到对应的flutter页面,那么native页面在哪注册的呢?FlutterBoost又是怎么根据url知道这是一个native页面呢?

其实在native的activity中需要继承BoostFlutterActivity然后实现getContainerName()方法,这个方法返回的url就是注册在FlutterBoost中的key

@Override
    public String getContainerName() {
        return "flutterPage";
    }

这样在Dart中就可以通过”flutterPage”这个url来打开这个native的页面了。当然除了要实现getContainerName()这个方法外,如果你的native页面需要跟flutter页面通信的话还需要实现getContainerParams(),这个方法返回一个map对象,里面存的键值对可以传给原生的flutter页面。

@Override
    public Map getContainerParams() {
        Map<String,String> params = new HashMap<>();
        params.put("aaa","bbb");
        return params;
    }

结语

关于FlutterBoost的介绍就这么多了,写的还算简单,权当笔记,以备后面忘了的话可以再翻翻~

转自我自己的公众号:FlutterBoost简单使用介绍

发表评论

邮箱地址不会被公开。 必填项已用*标注

相关