服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - 编程技术 - Flutter 2 Router 从入门到放弃 - 基本使用、区别&优势

Flutter 2 Router 从入门到放弃 - 基本使用、区别&优势

2021-08-02 22:19微医大前端技术周建华 编程技术

Flutter 2 主要带来的新特性有 Null 安全性趋于稳定,桌面和 Web 支持也正式宣布进入 stable 渠道,最受大家关注的就是 Add-to-App 相关的更新,从而改善 Flutter2 之前的版本混合开发体验不好缺点。

Flutter 2 Router 从入门到放弃 - 基本使用、区别&优势

前言

Flutter 2 主要带来的新特性有 Null 安全性趋于稳定,桌面和 Web 支持也正式宣布进入 stable 渠道,最受大家关注的就是 Add-to-App 相关的更新,从而改善 Flutter2 之前的版本混合开发体验不好缺点。所谓的 Add-to-App 就是将 Flutter 添加到现有的 iOS 和 Android 应用程序中来利用 Flutter,在两个移动平台上复用 Flutter 代码同时仍保留现有本机代码库的绝佳方法。在此方案出现之前,类似的第三方支持有 flutter_boost 、flutter_thrio 等,但是这些方案都要面对的问题是:非官方的支持必然存在每个版本需要适配的问题,而按照 Flutter 目前更新的速度,很可能每个季度的版本都存在较大的变动,所以如果开发者不维护或者维护不及时,那么侵入性极强的这类框架很容易就成为项目的瓶颈。

Flutter2 多引擎混合开发基本用法

1、先创建一个 Android 原生工程,( Android 原生项目工程创建过程略过)

2、Android 项目创建引入 Flutter Module,使用 File -> New- > New Module … -> 选择 Flutter Module ,然后指定一个 module name,填写相关息,最后点击确定,等待 Gradle sync 完成。

3、Android 项目集成 Flutter Module

1)创建 FlutterEngineGroup 对象,FlutterEngineGroup 可以用来管理多个 FlutterEngine 对象,多个 FlutterEngine 之间是可以共享资源的,这样多个 FlutterEngine 占用的资源相对会少一些,FlutterEngineGroup 需要在 Application onCreate 方法中创建。

  1. package com.zalex.hybird; 
  2.  
  3. import android.app.Application; 
  4. import io.flutter.embedding.engine.FlutterEngineGroup; 
  5.  
  6. public class WYApplication extends Application { 
  7.     public FlutterEngineGroup engineGroup; 
  8.     @Override 
  9.     public void onCreate() { 
  10.         super.onCreate(); 
  11.         // 创建 FlutterEngineGroup 对象 
  12.         engineGroup = new FlutterEngineGroup(this); 
  13.     } 

2)创建 WYFlutterEngineManager 缓存管理类,通过 FlutterEngineCache 缓存类,先从中获取缓存的 FlutterEngine,如果没有取到,通过 findAppBundlePath 和 entrypoint 创建出 DartEntrypoint 对象,这里的 findAppBundlePath 主要就是默认的 flutter_assets 目录;而 entrypoint 其实就是 dart 代码里启动方法的名称;也就绑定了在 dart 中 runApp 的方法,再通过 createAndRunEngine 方法创建一个 FlutterEngine,然后缓存起来。

  1. public class WYFlutterEngineManager { 
  2.     public static FlutterEngine flutterEngine(Context context, String engineId, String entryPoint) { 
  3.         // 1. 从缓存中获取 FlutterEngine 
  4.         FlutterEngine engine = FlutterEngineCache.getInstance().get(engineId); 
  5.         if (engine == null) { 
  6.             // 如果缓存中没有 FlutterEngine 
  7.             // 1. 新建 FlutterEngine,执行的入口函数是 entryPoint 
  8.            WYApplication app = (WYApplication) context.getApplicationContext(); 
  9.            DartExecutor.DartEntrypoint dartEntrypoint = new DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(), entryPoint); 
  10.            engine = app.engineGroup.createAndRunEngine(context, dartEntrypoint); 
  11.             // 2. 存入缓存 
  12.             FlutterEngineCache.getInstance().put(engineId, engine); 
  13.         } 
  14.         return engine; 
  15.     } 

Activity 绑定 flutter 引擎入口

  1. public class WYFlutterActivity extends FlutterActivity implements EngineBindingsDelegate { 
  2.     private WYFlutterBindings flutterBindings; 
  3.  
  4.     @Override 
  5.     protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { 
  6.         super.onCreate(savedInstanceState); 
  7.         flutterBindings = new WYFlutterBindings(this,SingleFlutterActivity.class.getSimpleName(),"main",this); 
  8.         flutterBindings.attach(); 
  9.     } 
  10.     @Override 
  11.     protected void onDestroy() { 
  12.         super.onDestroy(); 
  13.         flutterBindings.detach(); 
  14.     } 
  15.  
  16.     @Override 
  17.    public FlutterEngine provideFlutterEngine(@NonNull @NotNull Context context)  { 
  18.         return flutterBindings.getEngine(); 
  19.     } 
  20.  
  21.     @Override 
  22.     public void onNext() { 
  23.         Intent flutterIntent = new Intent(this, MainActivity.class); 
  24.         startActivity(flutterIntent); 
  25.     } 

Fragment 绑定 flutter 引擎入口

  1. int engineId = engineId ;//自定义引擎 Id 
  2. int fragmentId = 1233444;//自定义 FragmentId 
  3.  
  4. FrameLayout flutterContainer = new FrameLayout(this); 
  5. root.addView(flutterContainer); 
  6. flutterContainer.setId(containerId); 
  7. flutterContainer.setLayoutParams(new LinearLayout.LayoutParams( 
  8.         FrameLayout.LayoutParams.MATCH_PARENT, 
  9.         FrameLayout.LayoutParams.MATCH_PARENT, 
  10.         1.0f 
  11. )); 
  12.  
  13. WYFlutterBindings  flutterBindings = new WYFlutterBindings(this,"WYTopFragment","fragmentMain",this); 
  14.  
  15. FlutterEngine engine =  bottomBindings.getEngine(); 
  16.  
  17. FlutterEngineCache.getInstance().put(engineId+"", engine); 
  18. Fragment flutterFragment =FlutterFragment.withCachedEngine(engineId+"").build(); 
  19. fragmentManager 
  20.         .beginTransaction() 
  21.         .add(containerId, flutterFragment) 
  22.         .commit(); 

3)flutter 模块引擎入口绑定,除了 main 入口,其他引擎入口都需要加上@pragma('vm:entry-point')注解

  1. void main() => runApp(MyApp(Colors.blue)); 
  2.  
  3. @pragma('vm:entry-point'
  4. void fragmentMain() => runApp(CustomApp(Colors.green)); 

Flutter2多引擎混合开发与单引擎混合开发比较

1、 Flutter 多引擎方案是 flutter api 一直都是可以支持的,可以创建多个引擎,也可以渲染多个不同的界面,也是独立的,但是每次启动一个 flutter 引擎,都会占一个独立的引擎,通过测试可以发现,一个引擎 40M,创建 10 个引擎消耗了 235M,对内存的占用很大,在开发中是不可接受的。

2、由于 Flutter 2 之前版本多引擎的缺陷,业内的做法一般是对 isolate 或 engine 进行复用来解决。影响力较大的是以 FlutterBoost 和 Thrio 为代表的单引擎浏览器方案。即把 Activity/ViewController 作为承载 Dart 页面的浏览器,在页面切换时对单引擎进行 detach/attach,同时通知 Dart 层页面切换,来实现 Engine 的复用。由于只持有了一个 Engine 单例,仅创建一份 isolate,Dart 层是通信和资源共享的,内存损耗也得以有显著的降低。但是单引擎实现依赖于修改官方的 io.flutter 包,对 flutter 框架做出比较大的结构性修改。

3、从 Flutter 2 开始,多引擎下使用 FlutterEngineGroup 来创建新的 Engine,官方宣称内存损耗仅占 180K,其本质是使 Engine 可以共享 GPU 上下文、字形和 isolate group snapshot,从而实现了更快的初始速度和更低的内存占用。

4、Flutter 2 与 Flutter 1 创建引擎的区别:

Flutter1 引擎创建

  1. //Android 
  2. val engine = FlutterEngine(this) 
  3. engine.dartExecutor.executeDartEntrypoin(DartExecutor.DartEntrypoint.createDefault()) 
  4. FlutterEngineCache.getInstance().put(1,engine) 
  5. val intent = FlutterActivity.withCacheEngine(1).build(this) 
  1. //iOS 
  2. let engine = FlutterEngine() 
  3. engine.run() 
  4. let vc = FlutterViewController(engine:engine,nibName:nil,bundle:nil) 

Fluter2 引擎创建

  1. //Android 
  2. val engineGroup = FlutterEngineGroup(context) 
  3. val engine1 = engineGroup.createAndRunDefaultEngine(context) 
  4. val engine2 = engineGroup.createAndRunEngine(context,DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(),"anotherEntrypoint")) 
  1. //iOS 
  2. let engineGroup = FlutterEngineGroup(name:"example",project:nil) 
  3. let engine1 = engineGroup.makeEngine(withEntrypoint:nil,libraryURI:nil) 
  4. let engine2 = engineGroup.makeEngine(withEntrypoint:"anotherEntrypoint",libraryURI:nil) 

5、Flutter 混合开发方案比较

Flutter 2 Router 从入门到放弃 - 基本使用、区别&优势

6、Flutter 轻量级多引擎和单引擎优缺点比较

Flutter 2 Router 从入门到放弃 - 基本使用、区别&优势

后记 

本文通过代码和表格,我们讲述了 Flutter 2 多引擎使用、多引擎混合开发与单引擎混合开发区别和优缺点比较,下一节我们将一起去学习 Flutter 2 多引擎的实现原理。

原文链接:https://mp.weixin.qq.com/s/espmVAT16Lt_z24YeZo56A

延伸 · 阅读

精彩推荐
  • 编程技术AIOps,SRE工程师手中的利器

    AIOps,SRE工程师手中的利器

    AIOps开始成为一种极为重要的站点可靠性工程工具。它能够高效吸纳观察数据、参与数据以及来自第三方工具的数据,判断系统运行状态并保证其处于最佳...

    至顶网5972021-03-08
  • 编程技术简单、好懂的Svelte实现原理

    简单、好懂的Svelte实现原理

    本文会围绕一张流程图和两个Demo讲解,正确的食用方式是用电脑打开本文,跟着流程图、Demo一边看、一边敲、一边学...

    魔术师卡颂4822021-11-10
  • 编程技术2021年值得关注的React PDF 库

    2021年值得关注的React PDF 库

    今天,许多网络应用程序为其用户提供内置的PDF浏览选项。然而,选择一个并不容易,因为它们的功能远远超过显示PDF。在这篇文章中,我将评估5个React的...

    TianTianUp5232021-06-21
  • 编程技术Delphi - Indy idMessage和idSMTP实现邮件的发送

    Delphi - Indy idMessage和idSMTP实现邮件的发送

    这篇文章主要介绍了Delphi - Indy idMessage和idSMTP实现邮件的发送,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    JJ_JeremyWu6592020-09-22
  • 编程技术用户态 Tcpdump 如何实现抓到内核网络包的?

    用户态 Tcpdump 如何实现抓到内核网络包的?

    在网络包的发送和接收过程中,绝大部分的工作都是在内核态完成的。那么问题来了,我们常用的运行在用户态的程序 tcpdump 是那如何实现抓到内核态的包...

    开发内功修炼11612021-09-08
  • 编程技术真正聪明的程序员,总有办法不加班

    真正聪明的程序员,总有办法不加班

    工作效率提升了,就可以少加班了,聪明的程序员,总会有一堆可以提升编码效率的工具?当一种工具满足不了工作需求,就去探索新的,今天纬小创就给...

    今日头条12482021-03-04
  • 编程技术从Context源码实现谈React性能优化

    从Context源码实现谈React性能优化

    这篇文章主要介绍Context的实现原理,源码层面掌握React组件的render时机,从而写出高性能的React组件,源码层面了解shouldComponentUpdate、React.memo、PureComponen...

    魔术师卡颂5312020-12-20
  • 编程技术让开发效率倍增的 VS Code 插件

    让开发效率倍增的 VS Code 插件

    今天来分享一些提升开发效率的实用 VS Code 插件!Better Comments 扩展可以帮助我们在代码中创建更人性化的注释,有不同形式和颜色的注释供我们选择。 ...

    前端充电宝7132022-04-21