当前位置:首页 > 通信资讯 > 正文

flutter2教程(Flutter 2)

flutter2教程(Flutter 2)

前言

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. packagecom.zalex.hybird;
  2. importandroid.app.Application;
  3. importio.flutter.embedding.engine.FlutterEngineGroup;
  4. publicclassWYApplicationextendsApplication{
  5. publicFlutterEngineGroupengineGroup;
  6. @Override
  7. publicvoidonCreate(){
  8. super.onCreate();
  9. //创建FlutterEngineGroup对象
  10. engineGroup=newFlutterEngineGroup(this);
  11. }
  12. }

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

  1. publicclassWYFlutterEngineManager{
  2. publicstaticFlutterEngineflutterEngine(Contextcontext,StringengineId,StringentryPoint){
  3. //1.从缓存中获取FlutterEngine
  4. FlutterEngineengine=FlutterEngineCache.getInstance().get(engineId);
  5. if(engine==null){
  6. //如果缓存中没有FlutterEngine
  7. //1.新建FlutterEngine,执行的入口函数是entryPoint
  8. WYApplicationapp=(WYApplication)context.getApplicationContext();
  9. DartExecutor.DartEntrypointdartEntrypoint=newDartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(),entryPoint);
  10. engine=app.engineGroup.createAndRunEngine(context,dartEntrypoint);
  11. //2.存入缓存
  12. FlutterEngineCache.getInstance().put(engineId,engine);
  13. }
  14. returnengine;
  15. }
  16. }

Activity 绑定 flutter 引擎入口

  1. publicclassWYFlutterActivityextendsFlutterActivityimplementsEngineBindingsDelegate{
  2. privateWYFlutterBindingsflutterBindings;
  3. @Override
  4. protectedvoidonCreate(@Nullable@org.jetbrains.annotations.NullableBundlesavedInstanceState){
  5. super.onCreate(savedInstanceState);
  6. flutterBindings=newWYFlutterBindings(this,SingleFlutterActivity.class.getSimpleName(),"main",this);
  7. flutterBindings.attach();
  8. }
  9. @Override
  10. protectedvoidonDestroy(){
  11. super.onDestroy();
  12. flutterBindings.detach();
  13. }
  14. @Override
  15. publicFlutterEngineprovideFlutterEngine(@NonNull@NotNullContextcontext){
  16. returnflutterBindings.getEngine();
  17. }
  18. @Override
  19. publicvoidonNext(){
  20. IntentflutterIntent=newIntent(this,MainActivity.class);
  21. startActivity(flutterIntent);
  22. }
  23. }

Fragment 绑定 flutter 引擎入口

  1. intengineId=engineId;//自定义引擎Id
  2. intfragmentId=1233444;//自定义FragmentId
  3. FrameLayoutflutterContainer=newFrameLayout(this);
  4. root.addView(flutterContainer);
  5. flutterContainer.setId(containerId);
  6. flutterContainer.setLayoutParams(newLinearLayout.LayoutParams(
  7. FrameLayout.LayoutParams.MATCH_PARENT,
  8. FrameLayout.LayoutParams.MATCH_PARENT,
  9. 1.0f
  10. ));
  11. WYFlutterBindingsflutterBindings=newWYFlutterBindings(this,"WYTopFragment","fragmentMain",this);
  12. FlutterEngineengine=bottomBindings.getEngine();
  13. FlutterEngineCache.getInstance().put(engineId+"",engine);
  14. FragmentflutterFragment=FlutterFragment.withCachedEngine(engineId+"").build();
  15. fragmentManager
  16. .beginTransaction()
  17. .add(containerId,flutterFragment)
  18. .commit();

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

  1. voidmain()=>runApp(MyApp(Colors.blue));
  2. @pragma('vm:entry-point')
  3. voidfragmentMain()=>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. valengine=FlutterEngine(this)
  3. engine.dartExecutor.executeDartEntrypoin(DartExecutor.DartEntrypoint.createDefault())
  4. FlutterEngineCache.getInstance().put(1,engine)
  5. valintent=FlutterActivity.withCacheEngine(1).build(this)
  1. //iOS
  2. letengine=FlutterEngine()
  3. engine.run()
  4. letvc=FlutterViewController(engine:engine,nibName:nil,bundle:nil)

Fluter2 引擎创建

  1. //Android
  2. valengineGroup=FlutterEngineGroup(context)
  3. valengine1=engineGroup.createAndRunDefaultEngine(context)
  4. valengine2=engineGroup.createAndRunEngine(context,DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(),"anotherEntrypoint"))
  1. //iOS
  2. letengineGroup=FlutterEngineGroup(name:"example",project:nil)
  3. letengine1=engineGroup.makeEngine(withEntrypoint:nil,libraryURI:nil)
  4. letengine2=engineGroup.makeEngine(withEntrypoint:"anotherEntrypoint",libraryURI:nil)

5、Flutter 混合开发方案比较

flutter2教程(Flutter 2)

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

flutter2教程(Flutter 2)

后记

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

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

如果您对该产品感兴趣,请填写办理(客服微信:xiaoxiongyidong)

为您推荐:

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。