【Flutter混合开发】在Android项目中如何启动Flutter

news/2025/2/11 4:14:05/

在这里插入图片描述

目录

  • 前言
  • 现有项目中引入Flutter
  • 启动flutter页面
  • 加速启动
  • 启动传参
  • 总结

前言

flutter可以独立完成项目,但是在现有项目情况下最好的方式就是混合开发,逐步过渡。这样就会共存native和flutter代码,而其中最关键的就是native如何启动flutter页面,及flutter与native如何交互。

本文以Android为例,展示如何在一个现有项目中引入flutter、启动flutter,如何加速启动以及如何传参。

现有项目中引入Flutter

在现有的Android项目中,新建一个flutter module。创建完module后会发现自动在主module中依赖了。当然我们如果其他项目使用该flutter模块,并不会自动进行这一步,所以要先在setting.gradle中注册,如下:

setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir,'flutter_module/.android/include_flutter.groovy'
))include ':flutter_module'

然后在主module中依赖:

implementation project(path: ':flutter')

这样就可以进行混合开发了。

启动flutter页面

新建flutter module后会自动创建一个main页面,那么native如何打开这个页面?

首先在主module的manifest中添加:

       <activityandroid:name="io.flutter.embedding.android.FlutterActivity"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:hardwareAccelerated="true"android:windowSoftInputMode="adjustResize"/>

然后用一下代码即可打开flutter主页面

startActivity(FlutterActivity.createDefaultIntent(this))

那么如何打开其他页面?

比如我们创建一个新的flutter页面second:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';class SecondPage extends StatefulWidget{@overrideState<StatefulWidget> createState() {return _SecondPage();}}class _SecondPage extends State<SecondPage>{@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("test"),),body:Text("test"));}
}

然后在main.dart的App下注册这个页面:

class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: MyHomePage(title: 'Flutter Demo Home Page'),routes: {"second" : (BuildContext context) => SecondPage(),  //也可以用其他方式注册},);}
}

这样在flutter中可以用以下代码打开这个页面:

Navigator.of(context).pushNamed("second");

而在Android中就可以用以下代码即可打开该页面:

startActivity(FlutterActivity.withNewEngine().initialRoute("second").build(this))

加速启动

通过上面代码打开flutter页面时会出现黑屏现象,时间并不短,很影响体验。因为每次都重新new一个flutter engine( createDefaultIntent函数内部其实也是withNewEngine().build(launchContext) )。

官方给出的解决方案是使用engine cache,比如在Appliation中添加cache:

        var flutterEngine = FlutterEngine(this)flutterEngine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())FlutterEngineCache.getInstance().put("main", flutterEngine)

然后将启动改成:

startActivity(FlutterActivity.withCachedEngine("main").build(this))

但是上面仅仅是启动main页面,如果想启动其他页面,比如second,就需要继续添加cache:

        var flutterEngine2 = FlutterEngine(this)flutterEngine2.navigationChannel.setInitialRoute("second")flutterEngine2.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())FlutterEngineCache.getInstance().put("second", flutterEngine2)

注意这里通过setInitialRoute设置了route。然后启动即可:

startActivity(FlutterActivity.withCachedEngine("second").build(this))

通过缓存engine,启动时黑屏时间缩短了很多,几乎不可察觉(注意第一次可能还会稍微黑屏一下)。

启动传参

上面我们打开main和second页面没有传参,那么如果想传入一些初始化必要的参数,如何处理?

目前flutter框架并没有封装携带参数的api,也就是说native跳转flutter官方是没有参数。但是我们实际场景又有这样的需求,怎么处理?

官方没有给出相应的api,那么只能从route上想办法。首先改变app中注册route的方式,上面直接使用routes这种map的形式,我们换成onGenerateRoute这种RouteFactory形式,如下:

      onGenerateRoute: (RouteSettings settings) {if(settings.name.startsWith("second")){return MaterialPageRoute(builder: (BuildContext context) {return SecondPage(settings.name);});}else {return MaterialPageRoute(builder: (BuildContext context) {return Scaffold(body: Center(child: Text("page not found"),),);});}},

这里的settings.name就是route,因为我们想在route后面添加参数,所以通过开头来判断是那个页面。

注意:示例中直接将route url传给页面,其实应该在这里统一解析出来,以map的形式传给页面。

然后修改Second页面:

class SecondPage extends StatefulWidget{String url;SecondPage(String url){this.url = url;}@overrideState<StatefulWidget> createState() {return _SecondPage();}}class _SecondPage extends State<SecondPage>{@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("test"),),body:Text("test:${widget.url}"));}
}

这里没有解析,直接将url展示出来了,目的是参数传到位即可。

最后在native使用如下代码:

startActivity(FlutterActivity.withNewEngine().initialRoute("second?text=second test").build(this))

就可以传递参数了。

但是这样就引出了另外一个问题,因为上面这种启动方式并没有使用engine cache,如果使用engine cache那么route就必须提前定好以便在Appllication中放入cache中。但是我们既然要传参,那么说明route是动态改变的,所以这两个是冲突的,这样在传参的情况下就无法加速启动了么?

因为我们传参本身不是官方api的行为,所以官方的engine cache没有相应的支持。但是这个问题并不是无法解决,比如闲鱼开放的flutter混合框架 —— flutter-boost,就可以很轻松的实现native携参打开flutter页面。不过这里面涉及的东西比较多,首要的就是Flutter与原生的交互方式,这个可以看我的另外一篇博客《【Flutter进阶】与Native进行交互的三种方式》

总结

以上简单了解了一下如何在已有的Android项目中引入Flutter模块并启动页面,这样做的好处就是可以不对现有项目进行大规模的重构的同时通过Flutter来进行新的页面开发,逐渐过渡到Flutter。

本篇文章讲的是Android项目,那么Ios项目呢?请看
【Flutter混合开发】在已有iOS项目中引入Flutter


http://www.ppmy.cn/news/71570.html

相关文章

合肥工业大学信息隐藏实验报告

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;信息隐藏实验报告 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff…

SQL 常用函数总结(三)

数字处理函数 1. SUM() 函数功能&#xff1a;用于计算数值列的总和。 函数语法&#xff1a; SUM(column_name)column_name 表示需要计算总和的列名。 使用示例&#xff1a; 假设现在有一个名为 sales 的表&#xff0c;其中包含销售金额&#xff08;amount&#xff09;和销…

【Java】消息队列——ZeroMQ(ZMQ、0MQ)概述和使用演示

ZeroMQ&#xff08;简称ZMQ&#xff09;是一个高性能、开放源代码、免费的消息传递库&#xff0c;它提供了一种更加简单、更加轻量级的方式来进行网络通信。它的主要特点是高性能、低延迟、可靠性强、易用性好&#xff0c;易于在多语言环境中使用。ZeroMQ也是一个跨平台的库&am…

【机器视觉4】双目立体视觉标定

双目立体视觉标定的目的是标定左、右两个摄像机之间的坐标转换关系。 双目立体视觉的标定过程&#xff1a;采用MATLAB图像处理和计算机视觉库中的 Stereo Camera Calibrator(SCC)来标定双目立体视觉系统中左、右摄像机并获得左右摄像机的内参矩阵 M 1 M_1 M1​、 M 2 M_2 M2​…

五个阶段的实践清单-构想阶段实践

五个阶段的实践清单 构想阶段实践 商业论证、产品愿景、电梯测试、项目章程、团队形成与团队章程、项目数据表 商业论证框架 投资目标限于已有资金投资回报是与愿景相关联的收益流投资和回报与里程碑相关联里程碑确定时间&#xff0c;收益和成果与价值优先级排序的时间相关…

MySql.Data.dll 因版本问题造成报错的处理

NetCore 链接MySQL 报 Character set ‘utf8mb3‘ is not supported by .Net Framework 异常解决_character set utf8mb3_csdn_aspnet的博客-CSDN博客 查看mysql版本号&#xff0c;两种办法&#xff1a; 第一种在数据库中执行查询&#xff1a;SELECT version; 第二种使用工具…

数字化时代,如何从战略设计到架构来打造智慧银行?

导语 | 随着人工智能、大数据、云计算等技术向纵深发展&#xff0c;数字化转型已成为银行发展的“必答题”。调整战略规划和架构重组、加大信息科技投入、推进科技人才队伍建设、持续推出数字化产品……近年来&#xff0c;深化数字化转型&#xff0c;以科技赋能金融服务已成为不…

sql 性能优化基于explain调优(二)

文章目录 Explain问题描述解决方案 Explain 关于Explain具体怎么用以及有哪些优点&#xff0c;我就不过多的跟大家去讲解了&#xff0c;从我最初的文章: explain是什么&#xff1f;explain优缺点及如何使用explain优化SQL&#xff0c;大家可以点击这个链接看一下&#xff0c;对…