Flutter Android 混合开发之使用 FlutterBoost 4.0

2023-11-16

搜了下全网 FlutterBoost教程大都还是老版本,所有有了这篇。

当前使用环境

FlutterBoost 4.2.1

Flutter 3.3.4

首先根据官方文章集成 FlutterBoost

FlutterBoost 集成详细步骤

接下来开始填坑之旅

坑一:

此段代码在使用中会报个什么map转换错误,具体忘了。。。

 Map<String, Object> map = settings.arguments as Map<String, Object> ;

改为

Map<String, dynamic> map = settings.arguments as Map<String, dynamic>;

坑二:

此段代码当 routerMap[settings.name]  为 null 时,会报错:type 'Null' is not a subtype of type '(RouteSettings, String?) => Route<dynamic>' in type cast。

  Route<dynamic> routeFactory(RouteSettings settings, String uniqueId) {
    FlutterBoostRouteFactory func = routerMap[settings.name] as FlutterBoostRouteFactory;
    return func(settings, uniqueId);
  }

改为

  Route<dynamic>? routeFactory(RouteSettings settings, String? uniqueId) {
    FlutterBoostRouteFactory? func = routerMap[settings.name];
    if (func == null) return null;
    return func(settings, uniqueId);
  }

坑三:

在原生启动flutter直接进入报错界面。为什么呢?因为找不到 initialRoute 对应的界面。

查看源码:

class FlutterBoostApp extends StatefulWidget {
  FlutterBoostApp(
    FlutterBoostRouteFactory routeFactory, {
    Key? key,
    FlutterBoostAppBuilder? appBuilder,
    String? initialRoute,

    ///interceptors is to intercept push operation now
    List<BoostInterceptor>? interceptors,
  })  : appBuilder = appBuilder ?? _defaultAppBuilder,
        interceptors = interceptors ?? <BoostInterceptor>[],
        initialRoute = initialRoute ?? '/',
        super(key: key) {
    BoostNavigator.instance.routeFactory = routeFactory;
  }

initialRoute 为 null 就给个 '/',

在官方代码中没有注册  '/' 对应的界面,也没有给 initialRoute 赋值。

所以解决方法有二。

法一:注册一个 '/' 对应的界面

  Map<String, FlutterBoostRouteFactory> routerMap = {
    '/': (RouteSettings settings, String? uniqueId) {
      return MaterialPageRoute(
          settings: settings,
          builder: (_) {
            return MyHomePage(
              title: "主页",
            );
          });
    },
    。。。
  };

法二:给 initialRoute 个已注册的值

    return FlutterBoostApp(
      routeFactory,
      appBuilder: appBuilder,
      initialRoute: 'mainPage',
    );

基本路由API使用

使用 FlutterBoostActivity 和 FlutterBoostFragment 加载 flutter

改造前 

  FlutterBoost.instance().setup(this, new FlutterBoostDelegate() {
            @Override
            public void pushNativeRoute(FlutterBoostRouteOptions options) {
                //这里根据options.pageName来判断你想跳转哪个页面,这里简单给一个
                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 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(intent);
            }
        }, engine -> {
        });

改造后

       FlutterBoost.instance().setup(this, new FlutterBoostDelegate() {
            @Override
            public void pushNativeRoute(FlutterBoostRouteOptions options) {
                System.out.println("flutter to native requestCode:" + options.requestCode());
                if ("go_to_NativeActivity1".equals(options.pageName())) {
                    Intent intent = new Intent(FlutterBoost.instance().currentActivity(), NativeActivity1.class);
                    FlutterBoost.instance().currentActivity().startActivityForResult(intent, options.requestCode());
                } else if ("go_to_NativeActivity2".equals(options.pageName())) {
                    Map<String, Object> map = options.arguments();
                    Intent intent = new Intent(FlutterBoost.instance().currentActivity(), NativeActivity2.class);
                    intent.putExtra("data", (String) map.get("msg2222"));
                    FlutterBoost.instance().currentActivity().startActivity(intent);
                }
            }

            @Override
            public void pushFlutterRoute(FlutterBoostRouteOptions options) {
                Intent intent = new FlutterBoostActivity.CachedEngineIntentBuilder(FlutterBoostActivity.class)
                        .backgroundMode(options.opaque() ? FlutterActivityLaunchConfigs.BackgroundMode.opaque : FlutterActivityLaunchConfigs.BackgroundMode.transparent)
                        .destroyEngineWithActivity(false)
                        .uniqueId(options.uniqueId())
                        .url(options.pageName())
                        .urlParams(options.arguments())
                        .build(FlutterBoost.instance().currentActivity());

                if (options.requestCode() == 0) {
                    FlutterBoost.instance().currentActivity().startActivity(intent);
                } else {
                    FlutterBoost.instance().currentActivity().startActivityForResult(intent, options.requestCode());
                }
            }
        }, engine -> {

        });

FlutterBoostActivity

String[] options = {"无返回值", "有返回值"};
new AlertDialog.Builder(this)
        .setTitle("FlutterBoostActivity:原生启动 flutter ")
        .setItems(options, (dialog, which) -> {
            Map<String, Object> map = new HashMap<>();
            map.put("data", System.currentTimeMillis() + " by FlutterBoostActivity");

            FlutterBoostRouteOptions.Builder builder = new FlutterBoostRouteOptions.Builder()
                    .pageName("mainPage")
                    .opaque(false)
                    .arguments(map);

            if (which == 0) {
                map.put("hasResult", false);
            } else if (which == 1) {
                map.put("hasResult", true);
                builder.requestCode(1000);
            }

            FlutterBoost.instance().open(builder.build());
        }).show();

通过  FlutterBoost.instance().open(builder.build()); 启动会进入到 

public void pushFlutterRoute(FlutterBoostRouteOptions options){...}

FlutterBoostFragment

boolean hasResult = getIntent().getBooleanExtra("hasResult", false);

Map<String, Object> map = new HashMap<>();
map.put("data", System.currentTimeMillis() + " by FlutterBoostFragment");
map.put("hasResult", hasResult);

flutterBoostFragment = new FlutterBoostFragment.CachedEngineFragmentBuilder()
        .url("mainPage")
        .urlParams(map)
        .build();

getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.my_container, flutterBoostFragment)
        .commit();

接下来是flutter部分

              ElevatedButton(
                child: const Text('退出当前页面,返回参数给上一个Native页面'),
                onPressed: () {
                  // Navigator.of(context).pop({'retval' : 'I am from dart 11'});
                  BoostNavigator.instance.pop({'retval': 'I am from dart'});
                },
              )
            ElevatedButton(
              child: const Text('打开原生界面'),
              onPressed: () {
                BoostNavigator.instance
                    .push("go_to_NativeActivity1") // Native页面路由
                    .then((value) => showToast('from native retval:$value'));
              },
            )
            ElevatedButton(
              child: const Text('打开并传参给原生界面'),
              onPressed: () {
                BoostNavigator.instance.push(
                  "go_to_NativeActivity2",
                  withContainer: false,
                  arguments: {"msg2222": "hello,native boy"},
                  opaque: true,
                );
              },
            )
            ElevatedButton(
              child: const Text('打开一个 flutter 界面'),
              onPressed: () async {
                final result = await BoostNavigator.instance.push('simplePage1',
                    withContainer: false, arguments: {"data": "hello,flutter boy"}, opaque: false);

                /// withContainer为 false 时,也可以使用原生的 Navigator
                // final result = await Navigator.of(context).pushNamed('simplePage1', arguments: {"data": "hello,flutter boy 1111"});
                showToast(result);
              },
            )
            ElevatedButton(
              child: const Text('发送消息给 native'),
              onPressed: () async {
                BoostChannel.instance.sendEventToNative(
                    "flutter_to_native_event", {"msg5555555": "my ${DateTime.now().millisecondsSinceEpoch}"});
              },
            )

代码示例

转载请注明出处

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter Android 混合开发之使用 FlutterBoost 4.0 的相关文章

  • 以编程方式将 TextView 添加到主屏幕小部件

    我想以编程方式将文本视图控件添加到我的主屏幕小部件 在下面的示例中 我使用 TextView 填充 Linearlayout 但是这里应该如何使用 RemoteView 它只接受 xml 资源布局作为参数 public class MyWi
  • 如何在进入新活动之前终止线程和处理程序

    大家好 在我尝试清理处理程序时 这段代码可能有点混乱 因为我一直在尝试追踪崩溃发生的位置 我有一个对话框活动 显示密码输入 进度条由线程和处理程序动画显示 似乎当我试图查看进度条是否完成并尝试终止线程时 当我尝试进入新活动时 我这样做的方式
  • 无法加载或查找主类,可以在命令行中使用,但不能在 IDE 中使用[重复]

    这个问题在这里已经有答案了 在将其标记为重复之前 请先听我说完 我正在尝试使用 gradle 导入一个 java 项目 功能齐全 适用于所有其他笔记本电脑 没有问题 我的项目 100 正常运行 适用于所有其他笔记本电脑 当我的笔记本电脑被重
  • 如何将 Jfreechart(饼图)添加到 netbeans 的面板中

    我正在使用 netbeans gui 编辑器 并且正在尝试添加一个本身位于内部框架中的 Jfreechart 并且这个内部框架我想将其添加到面板中 正如您在此图中看到的那样 抱歉 我无法直接发布图像 因为我新手 http www flick
  • 计算日期之间的天数差异

    在我的代码中 日期之间的差异是错误的 因为它应该是 38 天而不是 8 天 我该如何修复 package random04diferencadata import java text ParseException import java t
  • Java - 返回值是否会中断循环?

    我正在编写一些基本上遵循以下格式的代码 public static boolean isIncluded E element Node
  • Cloudfoundry:如何组合两个运行时

    cloundfoundry 有没有办法结合两个运行时环境 我正在将 NodeJS 应用程序部署到 IBM Bluemix 现在 我还希望能够执行独立的 jar 文件 但应用程序失败 APP 0 bin sh 1 java not found
  • Spring Security OAuth2简单配置

    我有一个简单的项目 需要以下简单的配置 我有一个 密码 grant type 这意味着我可以提交用户名 密码 用户在登录表单中输入 并在成功时获得 access token 有了该 access token 我就可以请求 API 并获取用户
  • Espresso 和 Proguard 的 Java.lang.NoClassDefFoundError

    我对 Espresso 不太有经验 但我终于成功地运行了它 我有一个应用程序需要通过 Proguard 缩小才能处于 56K 方法之下 该应用程序以 3 秒的动画开始 因此我需要等到该动画结束才能继续 这就是我尝试用该方法做的事情waitF
  • Flutter基于Shared Preference设置启动页面

    我一直在尝试根据我的共享首选项设置加载不同的页面 但没有成功 根据 stackoverflow 中找到的几篇文章 我最终得到了以下解决方案 import dart async import package flutter material
  • onBackPressed 隐藏 不破坏 Activity

    我知道如何取消后退按键 以便活动 主窗口保持可见 public void onBackPressed return 我的目标是隐藏该活动 但是 在没有完成它的情况下 您如何在 onBackPressed 事件中做到这一点 即我想达到 onP
  • 如何通过 Inno Setup for NetBeans 使用自定义 .iss 文件

    我将 Inno Setup 5 与 NetBeans 8 一起使用 并且我已经能够创建一个安装程序来安装该应用程序C users username local appname 但是我希望将其安装在C Programfiles 我如何在 Ne
  • 为什么java中的for-each循环中需要声明变量

    for 每个循环的通常形式是这样的 for Foo bar bars bar doThings 但如果我想保留 bar 直到循环结束 我可以not使用 foreach 循环 Foo bar null Syntax error on toke
  • JSON 到 hashmap (杰克逊)

    我想将 JSON 转换为 HashMapJackson http jackson codehaus org 这是我的 JSON String json Opleidingen name Bijz trajecten zorg en welz
  • 在 Honeycomb Android 3.0 中显示 Action Bar 菜单项的图标

    我正在使用 Honeycomb android 3 0 开发 Android 应用程序 我正在尝试在 Action Bar 中显示菜单 菜单有一个图标和标题 当我们单击菜单项时 它会以下拉列表的形式显示其项目 它是下拉列表中带有项目名称但不
  • 安卓的限制

    我需要构建一个应用程序 该应用程序拍摄相机图像并将其上传到网络 在网络上进行一些处理并返回真 假 我在这方面遇到了一些问题 希望得到澄清 1 我的应用程序有什么方法可以知道 Android 相机捕获的图像吗 我从这里明白了什么 Androi
  • 在android中跟踪FTP上传数据?

    我有一个运行 Android 的 FTP 系统 但我希望能够在上传时跟踪字节 这样我就可以在上传过程中更新进度条 安卓可以实现这个功能吗 现在 我正在使用org apache common net ftp我正在使用的代码如下 另外 我在 A
  • 启动Java项目时发生类冲突:ClassMetadataReadingVisitor将接口org.springframework.asm.ClassVisitor作为超类

    我正在使用最新的Spring框架版本 3 2 2 RELEASE 开发一个Java Web项目 但是现在项目启动时遇到了问题 详细错误是 java lang IncompleteClassChangeError 类 org springfr
  • 在 Android 中使用 iText 将图像添加到特定位置

    我想使用 Android 中的 iText 将图像添加到 PDF 文件中的特定位置 这是一个可填写的表单 我添加了作为图像占位符的文本框 我想要做的就是像这样获取该文本框和图像 public class FormFill public st
  • 当ScrollView滚动到底部时加载更多数据

    我有一个带有动态加载内容的滚动视图 有时可能会有很多内容 所以我想在用户滚动到底部时加载更多内容 我搜索了合适的方法 发现了两种 onScrollChanged and getScrollY 但我不知道如何将它用于我的目的 请给我一些建议

随机推荐

  • CSS SASS 外部引入的scss文件中,不能用嵌套写法

    小记录 在vue文件中引入scss文件中 不能正常使用sass语法 发现是引入方式的问题
  • 【自我提升】Spring Data JPA之Specification动态查询详解

    写在前面 刷完Spring Data JPA的课后 发现Specification动态查询还挺有意思的 还应用到了规约设计模式 在此记录下学习过程和见解 目录 一 应用场景 二 源码解析 三 规约模式 四 实际应用 一 应用场景 1 简介
  • 云数据库知识学习——概述

    一 云计算是云数据库兴起的基础 云计算是分布式计算 并行计算 效用计算 网络存储 虚拟化 负载均衡等计算机和网络技术发展融合的产物 云计算是由一系列可以动态升级和被虚拟化的资源组成的 用户无需掌握云计算的技术 只要通过网络就可以访问这些资源
  • function XX declared implicitly

    stm32 keilMDK出现warning function XX declared implicitly 原创 2014年08月26日 14 50 47 26281 warning 223 D function CLR TX DATA
  • 枚举类,属性循环---(枚举类循环)通过名称取值

    代码示例 public enum DomeEnum AA 1 张三 BB 2 李四 CC 3 王五 DD 4 赵六 EE 5 李七 private Integer code private String name DomeEnum Inte
  • Qt 官方示例

    哈喽 我是老吴 最近又玩了一下 Qt 给大家分享一点 Qt 相关的基础知识吧 我个人非常喜欢 Qt 它简直就是我这个 C 手残党的利器 学习 Qt 的最佳途径应该是阅读官方的手册和示例 今天要分享的就是 Qt 官方提供的一个示例 http
  • 一种针对夏克哈特曼波前传感器质心数据求解波前斜率的处理方法

    一 导出质心数据 针对夏克哈特曼波前传感器 型号 索雷博 导出的质心数据 Save Centroid Date 本文提供一种基于质心数据的斜率矩阵获取及波前重构方法 图 1 哈特曼波前传感器导出质心数据 二 斜率矩阵求解 首先 通过Wave
  • 2023上半年京东运动鞋服市场数据分析(京东数据运营)

    大众线下运动生活恢复 掀起新一轮户外潮流 运动热潮迭起 由此产生的运动鞋服及专业装备需求 为运动品牌们带来了诸多增长机会 近日各大运动品牌陆续发布上半年财报 回答了品牌对复苏机遇 发展挑战的应对情况 接下来结合具体数据 我们一起来看一下运动
  • 【基础知识】一文看懂深度优先算法和广度优先算法

    概览 先上个图 现在我们要访问图中的每个节点 即图的遍历 图的遍历是指 从给定图中任意指定的顶点 称为初始点 出发 按照某种搜索方法沿着图的边访问图中的所有顶点 使每个顶点仅被访问一次 这个过程称为图的遍历 我们根据访问节点的顺序与方式 根
  • 【Redis】Redis实现点赞、点赞排行榜

    目录 一 点赞 1 思路 2 代码实现 二 点赞排行榜 1 思路 2 代码实现 一 点赞 1 思路 在我们的项目中我们有时候会碰到这样的需求 比如实现一个博客系统 当用户访问到这篇博客时可以进行点赞 那么这个功能如何去实现呢 我们可以在数据
  • JavaScript实现UTF-8字符集Base64编码

    下面是代码实现 function var BASE64 MAPPING 映射表 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n
  • 【Hexo】搭建自己的博客并到Github Pages

    一 什么是Hexo 用Hexo官网的介绍https hexo io zh cn docs Hexo是一个快速 简捷且高效的博客框架 Hexo使用Markdown解析文章 可以在很短的时间内生成静态网页 二 快速构建Hexo 安装Hexo之前
  • 【vue2】计算属性(computed)与侦听器(watch)详解

    博 主 初映CY的前说 前端领域 个人信条 想要变成得到 中间还有做到 本文核心 计算属性与侦听属性的用法 目录 文末有给大家准备好的Xmind思维导图 一 计算属性computed 默认get 方法 仅是获取值 不仅仅是获取值 还具有修改
  • Django 开发实战 1-3 创建子项目

    python 项目开发实战 创建Django 项目子应用 重应用模块 01 创建子项目 02 配置python py3 001 的开发环境 创建Django 项目子应用 重应用模块 项目背景 在这里插入图片描述 https img blog
  • Webpack的loader和plugin

    loader的作用 webpack中的loader是一个函数 主要为了实现源码的转换 所以loader函数会以源码作为参数 比如将ES6转换为ES5 将less转换为css 将css转换为js 以便能嵌入到html文件 常见的loader
  • html 视差效果,html5网页3D视差效果代码

    特效描述 html5网页 3D视差效果 html5网页3D视差效果代码 代码结构 1 引入CSS 2 引入JS 3 HTML代码 var ww wh function init t 0 ww window innerWidth wh win
  • win+r,cmd快捷操作合集

    1 appwiz cpl 程序和功能 2 calc 启动计算器 5 chkdsk exe Chkdsk磁盘检查 管理员身份运行命令提示符 6 cleanmgr 打开磁盘清理工具 9 cmd exe CMD命令提示符 10 自动关机命令 Sh
  • MySQL事务、日志、锁和MVCC机制

    InnoDB中事务的四大特性 原子性 当前事务的操作要么全部成功要么全部失败 原理 原子性是由undo log来保证的 undolog记录着数据修改之前的值 比如我们insert一条语句 undolog就会记录一条delete语句 我们up
  • 升级到 Ubuntu 18.04 LTS 的理由,大波新特性到来

    随着 2018 年 4 月 24 日稳定版正式发布日期的临近 也是时候来仔细研究下 Canonical 最新 Linux 发行版 Ubuntu 18 04 LTS Bionic Beaver 的最新功能特性了 LTS 版本每两年发布一次 而
  • Flutter Android 混合开发之使用 FlutterBoost 4.0

    搜了下全网 FlutterBoost教程大都还是老版本 所有有了这篇 当前使用环境 FlutterBoost 4 2 1 Flutter 3 3 4 首先根据官方文章集成 FlutterBoost FlutterBoost 集成详细步骤 接